diff --git a/group01/1298552064/src/week04/lru/LRUPageFrame.java b/group01/1298552064/src/week04/lru/LRUPageFrame.java new file mode 100644 index 0000000000..b00ff2c116 --- /dev/null +++ b/group01/1298552064/src/week04/lru/LRUPageFrame.java @@ -0,0 +1,116 @@ +package week04.lru; + +public class LRUPageFrame { + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node(Node prev, Node next, int pageNum) { + this.prev = prev; + this.next = next; + this.pageNum = pageNum; + } + } + + private int capacity; + + private Node first;// 链表头 + private Node last;// 链表尾 + private int size; // 链表长度 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + int index = find(pageNum); + if (size != 0) { + if(index >= 0){ + remove(index); + }else if(size == capacity){ + remove(size - 1); + } + } + addToHead(pageNum); + } + + public void remove(int index) { + if (index == 0) { + if(size == 1){ + first = last = null; + }else{ + first = first.next; + first.prev = null; + } + } else if (index == (size - 1)) { + if(size == 1){ + first = last = null; + }else{ + last = last.prev; + last.next = null; + } + } else { + Node node = first; + for (int i = 1; i < index; i++) { + node = node.next; + } + + Node nxt = node.next; + + node.next = nxt.next; + (nxt.next).prev = node; + nxt = null; + } + size--; + } + + public int find(int pageNum) { + int index = 0; + Node cur = first; + while (cur != null) { + if (pageNum == cur.pageNum) { + return index; + } + cur = cur.next; + index++; + } + return -1; + } + + public void addToHead(int pageNum) { + // 链表为空 + if (first == null) { + Node node = new Node(null, null, pageNum); + first = node; + last = node; + } else { + Node node = new Node(null,first,pageNum); + first.prev = node; + first = node; + } + size ++; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + Node node = first; + while (node != null) { + buffer.append(node.pageNum); + + node = node.next; + if (node != null) { + buffer.append(","); + } + } + return buffer.toString(); + } +} diff --git a/group01/1298552064/src/week04/minijvm/loader/ClassFileLoader.java b/group01/1298552064/src/week04/minijvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..2e80e89587 --- /dev/null +++ b/group01/1298552064/src/week04/minijvm/loader/ClassFileLoader.java @@ -0,0 +1,67 @@ +package week04.minijvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws IOException { + if(className == null){ + return null; + } + + boolean isFileExist = false; + File file = null; + String classPath = className.replace(".", "\\"); + for(int i = 0 ; i < clzPaths.size(); i++){ + String basePath = clzPaths.get(i); + file = new File(basePath + File.separator + classPath + ".class"); + + if(file.exists()){ + isFileExist = true; + break; + } + } + + //找不到类 + if(!isFileExist){ + throw new FileNotFoundException(); + } + + //读取字节码文件到数组 + FileInputStream in = new FileInputStream(file); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte [] rs = new byte[1024]; + int len = 0; + while((len = in.read(rs)) != -1){ + bos.write(rs, 0, len); + } + bos.close(); + in.close(); + System.out.println("readBinaryCode:" + " file size = " + file.length()); + return bos.toByteArray(); + } + + public void addClassPath(String path) { + if(! clzPaths.contains(path)){ + clzPaths.add(path); + } + } + + public String getClassPath() { + StringBuffer buffer = new StringBuffer(); + for(int i = 0;i < clzPaths.size();i++){ + buffer.append(clzPaths.get(i)); + if(i != clzPaths.size() - 1){ + buffer.append(";"); + } + } + return buffer.toString(); + } +} diff --git a/group01/1298552064/src/week04/test/ClassFileloaderTest.java b/group01/1298552064/src/week04/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..18b42f859d --- /dev/null +++ b/group01/1298552064/src/week04/test/ClassFileloaderTest.java @@ -0,0 +1,78 @@ +package week04.test; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import week04.minijvm.loader.ClassFileLoader; + + +public class ClassFileloaderTest { + static String path1 = "D:\\Git_2017\\coding2017\\group01\\1298552064\\bin"; + static String path2 = "C:\\temp"; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath() { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1 + ";" + path2, clzPath); + } + + @Test + public void testClassFileLength() throws IOException { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "week04.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1032, byteCodes.length); + + } + + @Test + public void testMagicNumber() throws IOException { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "week04.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[] { byteCodes[0], byteCodes[1], byteCodes[2], + byteCodes[3] }; + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + private String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group01/1298552064/src/week04/test/EmployeeV1.java b/group01/1298552064/src/week04/test/EmployeeV1.java new file mode 100644 index 0000000000..1c292f7744 --- /dev/null +++ b/group01/1298552064/src/week04/test/EmployeeV1.java @@ -0,0 +1,30 @@ +package week04.test; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} diff --git a/group01/1298552064/src/week04/test/LRUPageFrameTest.java b/group01/1298552064/src/week04/test/LRUPageFrameTest.java new file mode 100644 index 0000000000..6fbf3ddef9 --- /dev/null +++ b/group01/1298552064/src/week04/test/LRUPageFrameTest.java @@ -0,0 +1,29 @@ +package week04.test; + +import org.junit.Assert; +import org.junit.Test; + +import week04.lru.LRUPageFrame; + +public class LRUPageFrameTest { + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } +} diff --git a/group01/1814014897/zhouhui/.classpath b/group01/1814014897/zhouhui/.classpath index 373dce4005..fd40ed3fdb 100644 --- a/group01/1814014897/zhouhui/.classpath +++ b/group01/1814014897/zhouhui/.classpath @@ -3,5 +3,7 @@ + + diff --git a/group01/1814014897/zhouhui/src/week05/jvm/clz/AccessFlag.java b/group01/1814014897/zhouhui/src/week05/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..b843c8917e --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package week05.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group01/1814014897/zhouhui/src/week05/jvm/clz/ClassFile.java b/group01/1814014897/zhouhui/src/week05/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..3969967b24 --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/clz/ClassFile.java @@ -0,0 +1,75 @@ +package week05.jvm.clz; + +import week05.jvm.constant.ClassInfo; +import week05.jvm.constant.ConstantPool; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + + System.out.println("Super Class Name:"+ getSuperClassName()); + + + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/clz/ClassIndex.java b/group01/1814014897/zhouhui/src/week05/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..31fb6f9eea --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package week05.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group01/1814014897/zhouhui/src/week05/jvm/constant/ClassInfo.java b/group01/1814014897/zhouhui/src/week05/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..6756c37efa --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package week05.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index ; + public ClassInfo(ConstantPool pool) { + super(pool); + } + public int getUtf8Index() { + return utf8Index; + } + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/constant/ConstantInfo.java b/group01/1814014897/zhouhui/src/week05/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..91db6cd7ee --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package week05.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/constant/ConstantPool.java b/group01/1814014897/zhouhui/src/week05/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..352b55bc23 --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package week05.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/constant/FieldRefInfo.java b/group01/1814014897/zhouhui/src/week05/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..4827d6d90a --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package week05.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/constant/MethodRefInfo.java b/group01/1814014897/zhouhui/src/week05/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..d310854127 --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package week05.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/constant/NameAndTypeInfo.java b/group01/1814014897/zhouhui/src/week05/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..aaa5022dc3 --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package week05.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/constant/NullConstantInfo.java b/group01/1814014897/zhouhui/src/week05/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..d2ec4edcee --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package week05.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/constant/StringInfo.java b/group01/1814014897/zhouhui/src/week05/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..602a2948b1 --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package week05.jvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index; + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/constant/UTF8Info.java b/group01/1814014897/zhouhui/src/week05/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..d3fc7f9303 --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package week05.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/loader/ByteCodeIterator.java b/group01/1814014897/zhouhui/src/week05/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..76a6adeb8b --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,37 @@ +package week05.jvm.loader; + +import java.util.Arrays; + +import week05.jvm.util.Util; + +public class ByteCodeIterator { + byte[] codes; + int pos = 0; + + public ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public int nextU1ToInt() { + return Util.byteToInt(new byte[]{codes[pos++]}); + } + + public int nextU2ToInt() { + return Util.byteToInt(new byte[]{codes[pos++],codes[pos++]}); + } + + public String nextU4ToHexString() { + return Util.byteToHexString(new byte[]{codes[pos++],codes[pos++],codes[pos++],codes[pos++]}); + } + + public byte[] getBytes(int len) { + if(pos + len >= codes.length){ + throw new ArrayIndexOutOfBoundsException(); + } + + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos += len; + return data; + } + +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/loader/ClassFileLoader.java b/group01/1814014897/zhouhui/src/week05/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..f4561d2603 --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/loader/ClassFileLoader.java @@ -0,0 +1,134 @@ +package week05.jvm.loader; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +import week05.jvm.clz.ClassFile; + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + className = className.replace('.', File.separatorChar) +".class"; + + for(String path : this.clzPaths){ + + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if(codes != null){ + return codes; + } + } + + return null; + } + + private byte[] loadClassFile(String clzFileName) { + + File f = new File(clzFileName); + + try { + + return IOUtils.toByteArray(new FileInputStream(f)); + + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + + + public void addClassPath(String path) { + if(this.clzPaths.contains(path)){ + return; + } + + this.clzPaths.add(path); + + } + + + + public String getClassPath(){ + return StringUtils.join(this.clzPaths,";"); + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + + + + // ------------------------------backup------------------------ + public String getClassPath_V1(){ + + StringBuffer buffer = new StringBuffer(); + for(int i=0;i", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + + +} diff --git a/group01/1814014897/zhouhui/src/week05/jvm/test/EmployeeV1.java b/group01/1814014897/zhouhui/src/week05/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..e86ea0ce81 --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/test/EmployeeV1.java @@ -0,0 +1,28 @@ +package week05.jvm.test; + +public class EmployeeV1 { + + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + public void setAge(int age){ + this.age = age; + } + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + public static void main(String[] args){ + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group01/1814014897/zhouhui/src/week05/jvm/util/Util.java b/group01/1814014897/zhouhui/src/week05/jvm/util/Util.java new file mode 100644 index 0000000000..830e6bc26d --- /dev/null +++ b/group01/1814014897/zhouhui/src/week05/jvm/util/Util.java @@ -0,0 +1,24 @@ +package week05.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes){ + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i s.size() || len <= 0) return null; + + Object[] result = new Object[len]; + for(int i=0;i=0;i--){ + s.push(result[i]); + } + + return result; + } + + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz 使用堆栈检查字符串s中的括号是不是成对出现的。 例如s = + * "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true 如果 s = "([b{x]y})", + * 则该字符串中的括号不是成对出现的, 该方法返回false; + * + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + char[] arr = s.toCharArray(); + + Stack s1 = new Stack(); + Stack s2 = new Stack(); + + for(int i=arr.length-1;i>=0;i--){ + s1.push(arr[i]); + } + + for(int i=0;i=1;i--){ + Assert.assertEquals(i, s.pop()); + } + } + + @Test + public void testIsValidPairs() { + String s1 = "([e{d}f])"; + String s2 = "([b{x]y})"; + + Assert.assertTrue(StackUtil.isValidPairs(s1)); + Assert.assertFalse(StackUtil.isValidPairs(s2)); + } + +} diff --git a/group01/280646174/basic/src/main/java/com/coding2017/basic/stack/StackUtil.java b/group01/280646174/basic/src/main/java/com/coding2017/basic/stack/StackUtil.java new file mode 100644 index 0000000000..99d9e1cb6d --- /dev/null +++ b/group01/280646174/basic/src/main/java/com/coding2017/basic/stack/StackUtil.java @@ -0,0 +1,122 @@ +package com.coding2017.basic.stack; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +public class StackUtil { + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, + * 可以使用另外一个栈来辅助 取出栈顶, 把其他元素腾出去, 把栈顶放到栈底, 再把别的元素放回去 + */ + public static void reverse(Stack s) { + if (s == null || s.isEmpty()) { + return; + } + + Stack tempStack = new Stack(); + Integer bottom = null; // 到什么元素为止 + Integer temp; + + while (!reachBottom(s, bottom)) { + temp = (Integer) s.pop(); + while (!reachBottom(s, bottom)) { + tempStack.push(s.pop()); + } + s.push(temp); + while (!tempStack.isEmpty()) { + s.push(tempStack.pop()); + } + bottom = temp; + } + } + + private static boolean reachBottom(Stack stack, Integer bottom) { + return stack.isEmpty() || stack.peek() == bottom; + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s, Object o) { + Stack tempStack = new Stack(); + while (!s.isEmpty()) { + if (s.peek().equals(o)) { + s.pop(); + break; + } + tempStack.push(s.pop()); + } + while (!tempStack.isEmpty()) { + s.push(tempStack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param len + * @return + */ + public static Object[] getTop(Stack s, int len) { + Object[] result = new Object[len]; + Stack tempStack = new Stack(); + for (int i = 0; i < len; i++) { + if (s.isEmpty()) { + break; + } + result[i] = s.peek(); + tempStack.push(s.pop()); + } + while (!tempStack.isEmpty()) { + s.push(tempStack.pop()); + } + return result; + } + + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz 使用堆栈检查字符串s中的括号是不是成对出现的。 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + Stack stack = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (isRightBracket(c)) { + if (stack.isEmpty() || !isMatchBracket(stack.pop(), c)) { + return false; + } + } else if (isLeftBracket(c)) { + stack.push(c); + } + } + + return stack.isEmpty(); + } + + private static boolean isLeftBracket(Character character) { + final Set leftBrackets = ImmutableSet.copyOf(new Character[] { '(', '[', '{' }); + return leftBrackets.contains(character); + } + + private static boolean isRightBracket(Character character) { + final Set rightBrackets = ImmutableSet.copyOf(new Character[] { ')', ']', '}' }); + return rightBrackets.contains(character); + } + + private static boolean isMatchBracket(Character left, Character right) { + final Map bracketMap = ImmutableMap. builder().put(')', '(') + .put(']', '[').put('}', '{').build(); + return left.equals(bracketMap.get(right)); + } + +} diff --git a/group01/280646174/basic/src/main/java/com/coding2017/basic/stack/expr/InfixExpr.java b/group01/280646174/basic/src/main/java/com/coding2017/basic/stack/expr/InfixExpr.java new file mode 100644 index 0000000000..0f95b519dd --- /dev/null +++ b/group01/280646174/basic/src/main/java/com/coding2017/basic/stack/expr/InfixExpr.java @@ -0,0 +1,18 @@ +package com.coding2017.basic.stack.expr; + +public class InfixExpr { + String expr = null; + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + + return 0.0f; + } + + + + +} diff --git a/group01/280646174/basic/src/test/java/com/coding2017/basic/stack/StackUtilTest.java b/group01/280646174/basic/src/test/java/com/coding2017/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..d25e7aee3d --- /dev/null +++ b/group01/280646174/basic/src/test/java/com/coding2017/basic/stack/StackUtilTest.java @@ -0,0 +1,52 @@ +package com.coding2017.basic.stack; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.Stack; + +import static org.junit.Assert.*; + +/** + * Created by kaitao.li on 2017/4/15. + */ +public class StackUtilTest { + + private Stack mockStack() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + return s; + } + + @Test + public void testReverse() { + Stack s = mockStack(); + StackUtil.reverse(s); + Assert.assertArrayEquals(s.toArray(), new Integer[] { 5, 4, 3, 2, 1 }); + } + + @Test + public void testRemove() { + Stack s = mockStack(); + StackUtil.remove(s, 3); + Assert.assertArrayEquals(s.toArray(), new Integer[] {1, 2, 4, 5}); + } + + @Test + public void testGetTop() { + Stack s = mockStack(); + Object[] top = StackUtil.getTop(s, 2); + Assert.assertArrayEquals(s.toArray(), new Integer[]{1, 2, 3, 4, 5}); + Assert.assertArrayEquals(top, new Integer[] {5, 4}); + } + + @Test + public void testIsValidPairs() { + Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])")); + Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})")); + } +} \ No newline at end of file diff --git a/group01/280646174/basic/src/test/java/com/coding2017/basic/stack/expr/InfixExprTest.java b/group01/280646174/basic/src/test/java/com/coding2017/basic/stack/expr/InfixExprTest.java new file mode 100644 index 0000000000..0ded3f2a95 --- /dev/null +++ b/group01/280646174/basic/src/test/java/com/coding2017/basic/stack/expr/InfixExprTest.java @@ -0,0 +1,51 @@ +package com.coding2017.basic.stack.expr; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by kaitao.li on 2017/4/15. + */ +public class InfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + //InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); + { + InfixExpr expr = new InfixExpr("2+3*4+5"); + Assert.assertEquals(19.0, expr.evaluate(), 0.001f); + } + { + InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); + Assert.assertEquals(100.0, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("3*20/2"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("20/2*3"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("10-30+50"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + } +} \ No newline at end of file diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/bean/EmployeeV1.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/bean/EmployeeV1.java new file mode 100644 index 0000000000..4fdddbb2eb --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/bean/EmployeeV1.java @@ -0,0 +1,30 @@ +package com.coding2017.jvm.bean; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/clz/AccessFlag.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..b2d58a1b50 --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/clz/AccessFlag.java @@ -0,0 +1,26 @@ +package com.coding2017.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass() { + return (this.flagValue & 0x0001) != 0; + } + + public boolean isFinalClass() { + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/clz/ClassFile.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..19c738f8d4 --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/clz/ClassFile.java @@ -0,0 +1,77 @@ +package com.coding2017.jvm.clz; + +import com.coding2017.jvm.constant.ClassInfo; +import com.coding2017.jvm.constant.ConstantPool; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + public ClassIndex getClzIndex() { + return clzIndex; + } + + public AccessFlag getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + public ConstantPool getConstantPool() { + return pool; + } + + public int getMinorVersion() { + return minorVersion; + } + + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + + public int getMajorVersion() { + return majorVersion; + } + + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + public void print() { + + if (this.accessFlag.isPublicClass()) { + System.out.println("Access flag : public "); + } + System.out.println("Class Name:" + getClassName()); + + System.out.println("Super Class Name:" + getSuperClassName()); + + } + + private String getClassName() { + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo) this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + + private String getSuperClassName() { + ClassInfo superClass = (ClassInfo) this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/clz/ClassIndex.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..2844afe494 --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/clz/ClassIndex.java @@ -0,0 +1,22 @@ +package com.coding2017.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + + public int getSuperClassIndex() { + return superClassIndex; + } + + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/ClassInfo.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..e87c283295 --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/ClassInfo.java @@ -0,0 +1,28 @@ +package com.coding2017.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index; + + public ClassInfo(ConstantPool pool) { + super(pool); + } + + public int getUtf8Index() { + return utf8Index; + } + + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info) constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/ConstantInfo.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..9acf6d70fa --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/ConstantInfo.java @@ -0,0 +1,31 @@ +package com.coding2017.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo() { + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/ConstantPool.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..61f8f8d5ba --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/ConstantPool.java @@ -0,0 +1,31 @@ +package com.coding2017.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + public ConstantPool() { + + } + + public void addConstantInfo(ConstantInfo info) { + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantInfos.get(index); + } + + public String getUTF8String(int index) { + return ((UTF8Info) this.constantInfos.get(index)).getValue(); + } + + public Object getSize() { + return this.constantInfos.size() - 1; + } +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/FieldRefInfo.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..4f440c59d5 --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/FieldRefInfo.java @@ -0,0 +1,58 @@ +package com.coding2017.jvm.constant; + +public class FieldRefInfo extends ConstantInfo { + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() + " : " + typeInfo.getName() + ":" + typeInfo.getTypeInfo() + "]"; + } + + public String getClassName() { + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info) this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/MethodRefInfo.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..091bb4a5d3 --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/MethodRefInfo.java @@ -0,0 +1,57 @@ +package com.coding2017.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + + return getClassName() + " : " + this.getMethodName() + " : " + this.getParamAndReturnType(); + } + + public String getClassName() { + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo) pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo) pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/NameAndTypeInfo.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..cda8ec8cd4 --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,48 @@ +package com.coding2017.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo { + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + + public void setIndex1(int index1) { + this.index1 = index1; + } + + public int getIndex2() { + return index2; + } + + public void setIndex2(int index2) { + this.index2 = index2; + } + + public int getType() { + return type; + } + + public String getName() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info) pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info) pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString() { + return "(" + getName() + "," + getTypeInfo() + ")"; + } +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/NullConstantInfo.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..7ce288e868 --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/NullConstantInfo.java @@ -0,0 +1,14 @@ +package com.coding2017.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo() { + + } + + @Override + public int getType() { + return -1; + } + +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/StringInfo.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..6408f56b0a --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/StringInfo.java @@ -0,0 +1,27 @@ +package com.coding2017.jvm.constant; + +public class StringInfo extends ConstantInfo { + private int type = ConstantInfo.STRING_INFO; + private int index; + + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public String toString() { + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/UTF8Info.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..93bdd6f231 --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/constant/UTF8Info.java @@ -0,0 +1,37 @@ +package com.coding2017.jvm.constant; + +public class UTF8Info extends ConstantInfo { + private int type = ConstantInfo.UTF8_INFO; + private int length; + private String value; + + public UTF8Info(ConstantPool pool) { + super(pool); + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getType() { + return type; + } + + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value + ")]"; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/loader/ByteCodeIterator.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..566b251c32 --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,38 @@ +package com.coding2017.jvm.loader; + +import com.coding2017.jvm.util.ByteUtil; + +public class ByteCodeIterator { + + private byte[] data; + private int pos; + + public ByteCodeIterator(byte[] data) { + this.data = data; + pos = 0; + } + + public void skip(int n) { + pos += n; + } + + public int nextU1ToInt() { + return nextByteN(1)[0]; + } + + public int nextU2ToInt() { + return ByteUtil.bytesToInt(nextByteN(2)); + } + + public String nextU4ToString() { + return ByteUtil.byteToHexString(nextByteN(4)); + } + + public byte[] nextByteN(int n) { + byte[] bytes = new byte[n]; + for (int i = 0; i < n; i++) { + bytes[i] = data[pos++]; + } + return bytes; + } +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/loader/ClassFileLoader.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..74796fbbcf --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/loader/ClassFileLoader.java @@ -0,0 +1,81 @@ +package com.coding2017.jvm.loader; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.coding2017.jvm.clz.ClassFile; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; + +public class ClassFileLoader { + private static Joiner SEMICOLON_JOINER = Joiner.on(";").skipNulls(); + private static Splitter DOT_SPLITTER = Splitter.on(".").trimResults(); + private static Joiner SLASH_JOINER = Joiner.on("/").skipNulls(); + + private static String CLASS_SUFFIX = ".class"; + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + List list = DOT_SPLITTER.splitToList(className); + String childDirectory = SLASH_JOINER.join(list); + for (String clzPath : clzPaths) { + String fullPath = makeFullPath(clzPath, childDirectory); + if (fileExist(fullPath)) { + return readFileBytes(fullPath); + } + } + System.out.println("no this class file: " + className); + return null; + } + + private byte[] readFileBytes(String filePath) { + try { + File file = new File(filePath); + long length = file.length(); + byte[] fileBytes = new byte[(int) length]; + int readLength = new FileInputStream(filePath).read(fileBytes); + if (readLength != length) { + System.out.println("read file error. read length: " + readLength + ", full length : " + length); + return null; + } + return fileBytes; + } catch (IOException e) { + System.out.println("read file error. " + filePath); + return null; + } + } + + private boolean fileExist(String fullPath) { + File classFile = new File(fullPath); + return classFile.exists() && classFile.isFile(); + } + + private String makeFullPath(String clzPath, String childDirectory) { + if (clzPath.endsWith("/") || clzPath.endsWith("\\")) { + return clzPath + childDirectory + CLASS_SUFFIX; + } else { + return clzPath + "/" + childDirectory + CLASS_SUFFIX; + } + } + + public void addClassPath(String path) { + if (!clzPaths.contains(path)) { + clzPaths.add(path); + } + } + + public String getClassPath() { + return SEMICOLON_JOINER.join(clzPaths); + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + } + +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/loader/ClassFileParser.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..ff21b4fa0c --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/loader/ClassFileParser.java @@ -0,0 +1,99 @@ +package com.coding2017.jvm.loader; + +import com.coding2017.jvm.clz.AccessFlag; +import com.coding2017.jvm.clz.ClassFile; +import com.coding2017.jvm.clz.ClassIndex; +import com.coding2017.jvm.constant.*; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + ClassFile classFile = new ClassFile(); + + ByteCodeIterator iterator = new ByteCodeIterator(codes); + boolean check = checkMagicNumber(iterator); + if (!check) { + System.out.println("不是标准class文件, magic number不正确"); + return null; + } + + // 版本号 + classFile.setMinorVersion(iterator.nextU2ToInt()); + classFile.setMajorVersion(iterator.nextU2ToInt()); + + // 常量池 + classFile.setConstPool(parseConstantPool(iterator)); + + // 访问标志 + classFile.setAccessFlag(parseAccessFlag(iterator)); + + // this class and super class + classFile.setClassIndex(parseClassInfex(iterator)); + + return classFile; + } + + private boolean checkMagicNumber(ByteCodeIterator iterator) { + String magicNumber = iterator.nextU4ToString(); + return "cafebabe".equals(magicNumber); + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + AccessFlag accessFlag = new AccessFlag(iter.nextU2ToInt()); + return accessFlag; + } + + private ClassIndex parseClassInfex(ByteCodeIterator iter) { + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(iter.nextU2ToInt()); + classIndex.setSuperClassIndex(iter.nextU2ToInt()); + return classIndex; + + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + ConstantPool constantPool = new ConstantPool(); + int constantCount = iter.nextU2ToInt(); + constantPool.addConstantInfo(new NullConstantInfo()); + for (int i = 1; i < constantCount; i++) { + constantPool.addConstantInfo(parseConstantInfo(constantPool, iter)); + } + return constantPool; + } + + private ConstantInfo parseConstantInfo(ConstantPool constantPool, ByteCodeIterator iterator) { + int tag = iterator.nextU1ToInt(); + if (tag == ConstantInfo.UTF8_INFO) { + UTF8Info utf8Info = new UTF8Info(constantPool); + utf8Info.setLength(iterator.nextU2ToInt()); + utf8Info.setValue(new String(iterator.nextByteN(utf8Info.getLength()))); + return utf8Info; + } else if (tag == ConstantInfo.CLASS_INFO) { + ClassInfo classInfo = new ClassInfo(constantPool); + classInfo.setUtf8Index(iterator.nextU2ToInt()); + return classInfo; + } else if (tag == ConstantInfo.STRING_INFO) { + StringInfo stringInfo = new StringInfo(constantPool); + stringInfo.setIndex(iterator.nextU2ToInt()); + return stringInfo; + } else if (tag == ConstantInfo.FIELD_INFO) { + FieldRefInfo fieldRefInfo = new FieldRefInfo(constantPool); + fieldRefInfo.setClassInfoIndex(iterator.nextU2ToInt()); + fieldRefInfo.setNameAndTypeIndex(iterator.nextU2ToInt()); + return fieldRefInfo; + } else if (tag == ConstantInfo.METHOD_INFO) { + MethodRefInfo methodRefInfo = new MethodRefInfo(constantPool); + methodRefInfo.setClassInfoIndex(iterator.nextU2ToInt()); + methodRefInfo.setNameAndTypeIndex(iterator.nextU2ToInt()); + return methodRefInfo; + } else if (tag == ConstantInfo.NAME_AND_TYPE_INFO) { + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(constantPool); + nameAndTypeInfo.setIndex1(iterator.nextU2ToInt()); + nameAndTypeInfo.setIndex2(iterator.nextU2ToInt()); + return nameAndTypeInfo; + } else { + throw new RuntimeException("not support tag " + tag); + } + } + +} diff --git a/group01/280646174/jvm/src/main/java/com/coding2017/jvm/util/ByteUtil.java b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/util/ByteUtil.java new file mode 100644 index 0000000000..f1f3ec883f --- /dev/null +++ b/group01/280646174/jvm/src/main/java/com/coding2017/jvm/util/ByteUtil.java @@ -0,0 +1,29 @@ +package com.coding2017.jvm.util; + +/** + * Created by kaitao.li on 2017/4/16. + */ +public class ByteUtil { + + public static int bytesToInt(byte[] data) { + int result = 0; + for (int i = 0; i < data.length; i++) { + result = result * 256 + data[i]; + } + return result; + } + + public static String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group01/280646174/jvm/src/test/java/com/coding2017/jvm/loader/ClassFileLoaderTest.java b/group01/280646174/jvm/src/test/java/com/coding2017/jvm/loader/ClassFileLoaderTest.java new file mode 100644 index 0000000000..c25f6f2c0f --- /dev/null +++ b/group01/280646174/jvm/src/test/java/com/coding2017/jvm/loader/ClassFileLoaderTest.java @@ -0,0 +1,189 @@ +package com.coding2017.jvm.loader; + +import com.coding2017.jvm.clz.ClassFile; +import com.coding2017.jvm.clz.ClassIndex; +import com.coding2017.jvm.constant.*; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by kaitao.li on 2017/4/16. + */ +public class ClassFileLoaderTest { + + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; + + static String path1 = "/Users/kaitao.li/code/study/coding2017/group01/280646174/jvm/target/classes"; + static String path2 = "C:\\temp"; + + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "EmployeeV1"; + + clzFile = loader.loadClass(className); + clzFile.print(); + } + + @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 = "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.coding2017.week4.jvm.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[] { byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3] }; + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + private String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + + /** + * ---------------------------------------------------------------------- + */ + + + @Test + public void testVersion(){ + + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool(){ + + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + +} \ No newline at end of file diff --git a/group01/280646174/pom.xml b/group01/280646174/pom.xml index 75422ec638..cf3eefc767 100644 --- a/group01/280646174/pom.xml +++ b/group01/280646174/pom.xml @@ -10,6 +10,7 @@ 1.0-SNAPSHOT basic + jvm @@ -46,4 +47,17 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/group01/349209948/src/week2_0305/array/ArrayUtil.java b/group01/349209948/src/week2_0305/array/ArrayUtil.java new file mode 100644 index 0000000000..3158becf66 --- /dev/null +++ b/group01/349209948/src/week2_0305/array/ArrayUtil.java @@ -0,0 +1,246 @@ +package week2_0305.array; + +import java.util.ArrayList; + +public class ArrayUtil { + + /** + * 给定一个整形数组a , 对该数组的值进行置换 + 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] + 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] + * @param origin + * @return + */ + public void reverseArray(int[] origin){ + if (origin == null) { + throw new IllegalArgumentException(); + } + int temp = 0; + for (int i = 0; i< origin.length/2; i++) { + temp = origin[i]; + origin[i] = origin[origin.length - i]; + origin[origin.length - i] = temp; + } + } + + /** + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: + * {1,3,4,5,6,6,5,4,7,6,7,5} + * @param oldArray + * @return + */ + + public int[] removeZero(int[] oldArray){ + if (oldArray == null) { + throw new IllegalArgumentException(); + } + int[] newArray = new int[oldArray.length]; + int index = 0; + for (int i =0; i < oldArray.length; i ++){ + if (oldArray[i] == 0) { + continue; + } else { + newArray[index++] = oldArray[i]; + } + } + return copyOf(newArray, index); + } + + /** + * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 + * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * @param array1 + * @param array2 + * @return + */ + + public int[] merge(int[] array1, int[] array2){ + if (array1 == null || array2 == null) { + throw new IllegalArgumentException(); + } + int[] array3 = new int[array1.length + array2.length]; + int index1 = 0; + int index2 = 0; + int actualSize = 0; + for (int i = 0; i < array3.length; i ++) { + //把array2剩余的部分拷入数据 + if (index1 >= array1.length) { + arrayCopy(array2, index2, array3, i, array2.length - index2); + actualSize = i + array2.length - index2; + return copyOf(array3, actualSize); + } + if (index2 >= array2.length) { + arrayCopy(array1, index1, array3, i, array1.length - index1); + actualSize = i + array1.length - index1; + return copyOf(array3, actualSize); + } + if (array1[index1] < array2[index2]) { + array3[i] = array1[index1]; + index1 ++; + } else if (array1[index1] == array2[index2]) { + array3[i] = array1[index1]; + index1 ++; + index2 ++; + } else { + array3[i] = array2[index2]; + index2 ++; + } + } + // array1 he array2 均为 空数组的情况 + return new int[0]; + } + + private void arrayCopy(int[] src, int srcPos, int[] dest, int destPos, int length) { + for (int i = 0; i< length; i++) { + dest[destPos++] = src[srcPos++]; + } + } + + private int[] copyOf(int[] arr, int size) { + int[] dest = new int[size]; + for (int i = 0; i< size; i++) { + dest[i] = arr[i]; + } + return dest; + } + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 注意,老数组的元素在新数组中需要保持 + * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * [2,3,6,0,0,0] + * @param oldArray + * @param size + * @return + */ + public int[] grow(int [] oldArray, int size){ + if (oldArray == null || size <0) { + throw new IllegalArgumentException(); + } + int[] newArray = new int[oldArray.length + size]; + for (int i = 0; i < oldArray.length; i++) { + newArray[i] = oldArray[i]; + } + return newArray; + } + + /** + * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 + * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] + * max = 1, 则返回空数组 [] + * @param max + * @return + */ + public int[] fibonacci(int max){ + if (max < 0 ) { + throw new IllegalArgumentException(); + } else if (max == 1) { + return new int[0]; + } + ArrayList list = new ArrayList(); + list.add(1); + list.add(1); + int i = 0; + while(true) { + int num = (int)list.get(i) + (int)list.get(i+1); + if (num < max) { + list.add(num); + } else { + break; + } + } + return listToArray(list); + } + + private int[] listToArray(ArrayList list){ + int[] arr = new int[list.size()]; + for (int i = 0;i < list.size(); i++) { + arr[i] = (int)list.get(i); + } + return arr; + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + if (max <2) { + throw new IllegalArgumentException(); + } + ArrayList list = new ArrayList(); + for (int i = 2; i < max; i++) { + if (isPrime(i)) { + list.add(i); + } + } + return listToArray(list); + } + + public boolean isPrime(int m) { + for (int i = 1; i < m/2; i++) { + if (m % i == 0) { + return false; + } + } + return true; + } + + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + if (max < 0) { + throw new IllegalArgumentException(); + } + ArrayList list = new ArrayList(); + for (int i = 0; i< max; i++) { + if (isPerfectNumber(i)) { + list.add(i); + } + } + return listToArray(list); + } + + public boolean isPerfectNumber(int num) { + int sum = 0; + for (int i = 0; i < num; i++) { + if (num % i == 0) { + sum += i; + } + } + if (sum == num) { + return true; + } else { + return false; + } + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator){ + if (array == null) { + throw new IllegalArgumentException(); + } + + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < array.length; i++) { + builder.append(array[i]).append(seperator); + } + return builder.substring(0, builder.length() - seperator.length()); + } + + +} diff --git a/group01/349209948/src/week2_0305/litestruts/Configuration.java b/group01/349209948/src/week2_0305/litestruts/Configuration.java new file mode 100644 index 0000000000..a10ac1cef9 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/Configuration.java @@ -0,0 +1,95 @@ +package week2_0305.litestruts; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; +import org.jdom2.input.SAXBuilder; +import week2_0305.litestruts.ConfigurationException;; + +public class Configuration { + Map actions = new HashMap<>(); + + public Configuration(String fileName) { + + String packageName = this.getClass().getPackage().getName(); + + packageName = packageName.replace('.', '/'); + + InputStream is = this.getClass().getResourceAsStream("/" + packageName + "/" + fileName); + + parseXML(is); + + try { + is.close(); + } catch (IOException e) { + throw new ConfigurationException(e); + } + } + + private void parseXML(InputStream is) { + SAXBuilder builder = new SAXBuilder(); + try { + Document doc = builder.build(is); + Element root = doc.getRootElement(); + for (Element actionElement : root.getChildren("action")) { + String actionName = actionElement.getAttributeValue("name"); + String clzName = actionElement.getAttributeValue("class"); + ActionConfig ac = new ActionConfig(actionName, clzName); + for (Element resultElement : actionElement.getChildren("result")) { + String resultName = resultElement.getAttributeValue("name"); + String viewName = resultElement.getText().trim(); + + ac.addViewResult(resultName, viewName); + } + this.actions.put(actionName, ac); + } + } catch (IOException e) { + throw new ConfigurationException(e); + } catch (JDOMException e) { + throw new ConfigurationException(e); + } + } + + public String getClassName(String action) { + ActionConfig ac = this.actions.get(action); + if (ac == null) { + return null; + } + return ac.getClassName(); + } + + public String getResultView(String actionName, String resultName) { + ActionConfig ac = this.actions.get(actionName); + if (ac == null) { + return null; + } + return ac.getViewName(resultName); + } + + private static class ActionConfig { + String name; + String clzName; + Map viewResult = new HashMap<>(); + + public ActionConfig(String actionName, String clzName) { + this.name = actionName; + this.clzName = clzName; + } + + public String getClassName() { + return this.clzName; + } + + public void addViewResult(String name, String viewName) { + viewResult.put(name, viewName); + } + + public String getViewName(String resultName) { + return viewResult.get(resultName); + } + } +} diff --git a/group01/349209948/src/week2_0305/litestruts/ConfigurationException.java b/group01/349209948/src/week2_0305/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..d80baae668 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/ConfigurationException.java @@ -0,0 +1,18 @@ +package week2_0305.litestruts; +import java.io.IOException; +import org.jdom2.JDOMException; + +public class ConfigurationException extends RuntimeException{ + + public ConfigurationException(String msg) { + super(msg); + } + + public ConfigurationException(JDOMException e) { + super(e); + } + + public ConfigurationException(IOException e) { + super(e); + } +} diff --git a/group01/349209948/src/week2_0305/litestruts/ConfigurationTest.java b/group01/349209948/src/week2_0305/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..3c2bf82ecc --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/ConfigurationTest.java @@ -0,0 +1,51 @@ +package week2_0305.litestruts; + +import week2_0305.litestruts.Configuration; + +import org.junit.Assert; +import org.junit.Test; + +public class ConfigurationTest { + + Configuration cfg = new Configuration("struts.xml"); + + @Test + public void testGetClassName() { + String clzName = cfg.getClassName("login"); + Assert.assertEquals("week2_0305.litestruts.LoginAction", clzName); + clzName = cfg.getClassName("logout"); + Assert.assertEquals("week2_0305.litestruts.LogoutAction", clzName); + } + @Test + public void testGetFileName() { + String packageName = this.getClass().getPackage().getName(); + packageName = packageName.replace('.', '/'); + packageName = "/" + packageName + "/" + "struts.xml"; + Assert.assertEquals("/week2_0305/litestruts/struts.xml", packageName); + } + + @Test + public void testGetResultView() { + String actionName = "login"; + String resultName = "success"; + String viewName = cfg.getResultView(actionName, resultName); + Assert.assertEquals("/jsp/homepage.jsp", viewName); + + actionName = "login"; + resultName = "fail"; + viewName = cfg.getResultView(actionName, resultName); + Assert.assertEquals("/jsp/showLogin.jsp", viewName); + + actionName = "logout"; + resultName = "success"; + viewName = cfg.getResultView(actionName, resultName); + Assert.assertEquals("/jsp/welcome.jsp", viewName); + + actionName = "logout"; + resultName = "error"; + viewName = cfg.getResultView(actionName, resultName); + Assert.assertEquals("/jsp/error.jsp", viewName); + + } + +} diff --git a/group01/349209948/src/week2_0305/litestruts/LoginAction.java b/group01/349209948/src/week2_0305/litestruts/LoginAction.java new file mode 100644 index 0000000000..ed666b6645 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/LoginAction.java @@ -0,0 +1,39 @@ +package week2_0305.litestruts; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LoginAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group01/349209948/src/week2_0305/litestruts/ReflectionUtil.java b/group01/349209948/src/week2_0305/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..a670d6df04 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/ReflectionUtil.java @@ -0,0 +1,74 @@ +package week2_0305.litestruts; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + List methods = new ArrayList<>(); + for (Method m : clz.getDeclaredMethods()) { + if (m.getName().startsWith("set")) { + methods.add(m); + } + } + return methods; + } + + public static List getGetterMethods(Class clz) { + List methods = new ArrayList(); + for (Method m : clz.getDeclaredMethods()) { + if (m.getName().startsWith("get")) { + methods.add(m); + } + } + return methods; + } + + public static List getMethods(Class clz, String startWithName) { + List methods = new ArrayList<>(); + for (Method m : clz.getDeclaredMethods()) { + if (m.getName().startsWith(startWithName)) { + methods.add(m); + } + } + return methods; + } + + public static void setParameters(Object o, Map params) { + List methods = getSetterMethods(o.getClass()); + for (String name : params.keySet()) { + String methodName = "set" + name; + for (Method m : methods) { + if (m.getName().equalsIgnoreCase(methodName)) { + try { + m.invoke(o, params.get(name)); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + } + + public static Map getParamterMap(Object o) { + Map params = new HashMap<>(); + List methods = getGetterMethods(o.getClass()); + for (Method m : methods) { + String methodName = m.getName(); + String name = methodName.replaceFirst("get", "").toLowerCase(); + try { + Object value = m.invoke(o); + params.put(name, value); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + } + return params; + } + +} diff --git a/group01/349209948/src/week2_0305/litestruts/ReflectionUtilTest.java b/group01/349209948/src/week2_0305/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..242487da60 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/ReflectionUtilTest.java @@ -0,0 +1,130 @@ +package week2_0305.litestruts; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; + +public class ReflectionUtilTest { + + @Test + public void testGetSetterMethod() throws Exception{ + String name = "week2_0305.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getSetterMethods(clz); + + Assert.assertEquals(2, methods.size()); + + List expectNames = new ArrayList<>(); + expectNames.add("setName"); + expectNames.add("setPassword"); + + Set actualNames = new HashSet<>(); + for(Method m : methods) { + actualNames.add(m.getName()); + } + Assert.assertTrue(actualNames.containsAll(expectNames)); + } + + @Test + public void testSetParameters() throws Exception{ + String name = "week2_0305.litestruts.LoginAction"; + Class clz = Class.forName(name); + Object o = clz.newInstance(); + + Map params = new HashMap(); + params.put("name", "test"); + params.put("password", "123456"); + + ReflectionUtil.setParameters(o, params); + + Field f = clz.getDeclaredField("name"); + f.setAccessible(true); + Assert.assertEquals("test", f.get(o)); + + f = clz.getDeclaredField("password"); + f.setAccessible(true); + Assert.assertEquals("123456", f.get(o)); + } + + @Test + public void testGetGetterMethod() throws Exception{ + String name = "week2_0305.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getGetterMethods(clz); + + Assert.assertEquals(3, methods.size()); + List expectNames = new ArrayList<>(); + expectNames.add("getName"); + expectNames.add("getPassword"); + expectNames.add("getMessage"); + + Set actualNames = new HashSet<>(); + + for(Method m : methods) { + actualNames.add(m.getName()); + } + Assert.assertTrue(actualNames.containsAll(expectNames)); + + } + + @Test + public void testGetMethods() throws Exception{ + String name = "week2_0305.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getMethods(clz, "get"); + + Assert.assertEquals(3, methods.size()); + List expectNames = new ArrayList<>(); + expectNames.add("getName"); + expectNames.add("getPassword"); + expectNames.add("getMessage"); + + Set actualNames = new HashSet<>(); + + for(Method m : methods) { + actualNames.add(m.getName()); + } + Assert.assertTrue(actualNames.containsAll(expectNames)); + + methods = ReflectionUtil.getMethods(clz, "set"); + + Assert.assertEquals(2, methods.size()); + + expectNames = new ArrayList<>(); + expectNames.add("setName"); + expectNames.add("setPassword"); + + actualNames = new HashSet<>(); + for(Method m : methods) { + actualNames.add(m.getName()); + } + Assert.assertTrue(actualNames.containsAll(expectNames)); + } + + @Test + public void testGetParameters() throws Exception{ + String name = "week2_0305.litestruts.LoginAction"; + Class clz = Class.forName(name); + LoginAction action = (LoginAction)clz.newInstance(); + action.setName("test"); + action.setPassword("123456"); + + Map params = ReflectionUtil.getParamterMap(action); + + Assert.assertEquals(3, params.size()); + + Assert.assertEquals(null, params.get("message")); + Assert.assertEquals("test", params.get("name")); + Assert.assertEquals("123456", params.get("password")); + + } + +} diff --git a/group01/349209948/src/week2_0305/litestruts/Struts.java b/group01/349209948/src/week2_0305/litestruts/Struts.java new file mode 100644 index 0000000000..4b97a947c1 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/Struts.java @@ -0,0 +1,55 @@ +package week2_0305.litestruts; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; + + + +public class Struts { + + private final static Configuration cfg = new Configuration("struts.xml"); + public static View runAction(String actionName, Map parameters) { + + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + String clzName = cfg.getClassName(actionName); + + try { + Class clz = Class.forName(clzName); + Object action = clz.newInstance(); + ReflectionUtil.setParameters(action, parameters); + Method m = clz.getDeclaredMethod("execute"); + String resultName = (String) m.invoke(action); + String jsp = cfg.getResultView(actionName, resultName); + Map params = ReflectionUtil.getParamterMap(action); + View view = new View(); + view.setJsp(jsp); + view.setParameters(params); + return view; + + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + +} diff --git a/group01/349209948/src/week2_0305/litestruts/StrutsTest.java b/group01/349209948/src/week2_0305/litestruts/StrutsTest.java new file mode 100644 index 0000000000..3b4ce1d7d1 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/StrutsTest.java @@ -0,0 +1,43 @@ +package week2_0305.litestruts; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + + + + + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() { + + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } +} diff --git a/group01/349209948/src/week2_0305/litestruts/View.java b/group01/349209948/src/week2_0305/litestruts/View.java new file mode 100644 index 0000000000..a414cad3e5 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/View.java @@ -0,0 +1,23 @@ +package week2_0305.litestruts; + +import java.util.Map; + +public class View { + private String jsp; + private Map parameters; + + public String getJsp() { + return jsp; + } + public View setJsp(String jsp) { + this.jsp = jsp; + return this; + } + public Map getParameters() { + return parameters; + } + public View setParameters(Map parameters) { + this.parameters = parameters; + return this; + } +} diff --git a/group01/765324639/pom.xml b/group01/765324639/pom.xml new file mode 100644 index 0000000000..24816f0f3f --- /dev/null +++ b/group01/765324639/pom.xml @@ -0,0 +1,18 @@ + + 4.0.0 + com.zavier + 765324639Learning + 0.0.1-SNAPSHOT + + + junit + junit + 4.12 + + + dom4j + dom4j + 1.6.1 + + + \ No newline at end of file diff --git a/group01/765324639/src/main/java/datastructure/BinaryTreeNode.java b/group01/765324639/src/main/java/datastructure/BinaryTreeNode.java new file mode 100644 index 0000000000..20d0734f11 --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/BinaryTreeNode.java @@ -0,0 +1,63 @@ +package datastructure; + +public class BinaryTreeNode { + + private Integer data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public BinaryTreeNode(Integer data) { + this.data = data; + } + + public Integer getData() { + return data; + } + + public void setData(Integer 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(Integer o) { + + if (o > this.data) { + + if (this.getRight() == null) { + BinaryTreeNode node = new BinaryTreeNode(o); + this.setRight(node); + return node; + } else { + return this.getRight().insert(o); + } + + } else { + + if (this.getLeft() == null) { + BinaryTreeNode node = new BinaryTreeNode(o); + this.setLeft(node); + return node; + } else { + return this.getLeft().insert(o); + } + + } + + } + +} diff --git a/group01/765324639/src/main/java/datastructure/Iterator.java b/group01/765324639/src/main/java/datastructure/Iterator.java new file mode 100644 index 0000000000..ae54040424 --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/Iterator.java @@ -0,0 +1,8 @@ +package datastructure; + +public interface Iterator { + public boolean hasNext(); + + public Object next(); + +} diff --git a/group01/765324639/src/main/java/datastructure/List.java b/group01/765324639/src/main/java/datastructure/List.java new file mode 100644 index 0000000000..507cca34a8 --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/List.java @@ -0,0 +1,13 @@ +package 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/765324639/src/main/java/datastructure/Queue.java b/group01/765324639/src/main/java/datastructure/Queue.java new file mode 100644 index 0000000000..d4cfec525e --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/Queue.java @@ -0,0 +1,27 @@ +package datastructure; + +import datastructure.linkedlist.LinkedList; + +public class Queue { + + private LinkedList list = new LinkedList(); + + public void enQueue(Object o) { + list.add(o); + } + + public Object deQueue() { + if (list.size() == 0) { + return null; + } + return list.removeFirst(); + } + + public boolean isEmpty() { + return list.size() == 0; + } + + public int size() { + return list.size(); + } +} diff --git a/group01/765324639/src/main/java/datastructure/array/ArrayList.java b/group01/765324639/src/main/java/datastructure/array/ArrayList.java new file mode 100644 index 0000000000..a4b4182226 --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/array/ArrayList.java @@ -0,0 +1,88 @@ +package datastructure.array; + +import java.util.Arrays; + +import datastructure.Iterator; +import datastructure.List; + +public class ArrayList implements List { + + private int size = 0; + + private Object[] elementData = new Object[100]; + + @Override + public void add(Object o) { + ensureCapacity(size + 1); + elementData[size++] = o; + } + + private void ensureCapacity(int size) { + if (size > elementData.length) { + grow(); + } + } + + private void grow() { + elementData = Arrays.copyOf(elementData, size * 2); + } + + @Override + public void add(int index, Object o) { + rangeCheckForAdd(index); + ensureCapacity(size + 1); + System.arraycopy(elementData, index, elementData, index + 1, size - index); + elementData[index] = o; + size++; + } + + private void rangeCheckForAdd(int index) { + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException(); + } + } + + @Override + public Object get(int index) { + rangeCheck(index); + return elementData[index]; + } + + private void rangeCheck(int index) { + if (index >= size || index < 0) { + throw new IndexOutOfBoundsException(); + } + } + + @Override + public Object remove(int index) { + rangeCheck(index); + Object dest = elementData[index]; + System.arraycopy(elementData, index + 1, elementData, index, size - index - 1); + size--; + return dest; + } + + @Override + public int size() { + return size; + } + + public Iterator iterator() { + return new Iterator() { + + private int index = 0; + + @Override + public Object next() { + return elementData[index++]; + } + + @Override + public boolean hasNext() { + return index < size; + } + }; + } + +} diff --git a/group01/765324639/src/main/java/datastructure/array/ArrayUtil.java b/group01/765324639/src/main/java/datastructure/array/ArrayUtil.java new file mode 100644 index 0000000000..74040ccbe0 --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/array/ArrayUtil.java @@ -0,0 +1,262 @@ +package datastructure.array; + +import datastructure.List; + +public class ArrayUtil { + + /** + * 给定一个整形数组a , 对该数组的值进行置换 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] 如果 a = [7, 9, 30, 3, 4] , + * 置换后为 [4,3, 30 , 9,7] + * + * @param origin + * @return + */ + public void reverseArray(int[] origin) { + if (origin == null) { + throw new IllegalArgumentException(); + } + + int temp; + for (int i = 0; i < origin.length / 2; i++) { + temp = origin[i]; + origin[i] = origin[origin.length - 1 - i]; + origin[origin.length - 1 - i] = temp; + } + } + + /** + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: {1,3,4,5,6,6,5,4,7,6,7,5} + * + * @param oldArray + * @return + */ + + public int[] removeZero(int[] oldArray) { + if (oldArray == null) { + throw new IllegalArgumentException(); + } + + int[] noZeroArray = new int[oldArray.length]; + int index = 0; + for (int i = 0; i < oldArray.length; i++) { + if (oldArray[i] != 0) { + noZeroArray[index++] = oldArray[i]; + } + } + + return copyOf(noZeroArray, index); + } + + /** + * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 例如 a1 = [3, 5, 7,8] a2 = [4, + * 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * + * @param array1 + * @param array2 + * @return + */ + + public int[] merge(int[] array1, int[] array2) { + if (array1 == null || array2 == null) { + throw new IllegalArgumentException(); + } + + int indexOfArray1 = 0; + int indexOfArray2 = 0; + int totalLength = array1.length + array2.length; + int[] destArr = new int[totalLength]; + + for (int i = 0; i < totalLength; i++) { + if (indexOfArray1 >= array1.length) { + // array1填充完毕,将array2填充剩下的元素 + arrayCopy(array2, indexOfArray2, destArr, i, array2.length - indexOfArray2); + int actualSize = i + array2.length - indexOfArray2; + return copyOf(destArr, actualSize); + } + + if (indexOfArray2 >= array2.length) { + arrayCopy(array1, indexOfArray1, destArr, i, array1.length - indexOfArray1); + int actualSize = i + array1.length - indexOfArray1; + return copyOf(destArr, actualSize); + } + + if (array1[indexOfArray1] < array2[indexOfArray2]) { + destArr[i] = array1[indexOfArray1]; + indexOfArray1++; + } else if (array1[indexOfArray1] == array2[indexOfArray2]) { + destArr[i] = array1[indexOfArray1]; + indexOfArray1++; + indexOfArray2++; // 去除重复元素 + } else { + destArr[i] = array2[indexOfArray2]; + indexOfArray2++; + } + + } + // array1.length、array2.length均为0的情况 + return new int[0]; + } + + private void arrayCopy(int[] src, int srcPos, int[] dest, int destPos, int length) { + for (int i = 0; i < length; i++) { + dest[destPos++] = src[srcPos++]; + } + } + + private int[] copyOf(int[] original, int newLength) { + int[] dest = new int[newLength]; + for (int i = 0; i < newLength; i++) { + dest[i] = original[i]; + } + return dest; + } + + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size 注意,老数组的元素在新数组中需要保持 例如 oldArray + * = [2,3,6] , size = 3,则返回的新数组为 [2,3,6,0,0,0] + * + * @param oldArray + * @param size + * @return + */ + public int[] grow(int[] oldArray, int size) { + if (oldArray == null || size < 0) { + throw new IllegalArgumentException(); + } + + int newSize = oldArray.length + size; + int[] newArray = new int[newSize]; + for (int i = 0; i < oldArray.length; i++) { + newArray[i] = oldArray[i]; + } + return newArray; + } + + /** + * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] + * max = 1, 则返回空数组 [] + * + * @param max + * @return + */ + public int[] fibonacci(int max) { + if (max < 0) { + throw new IllegalArgumentException(); + } + if (max == 1) { + return new int[] {}; + } + + ArrayList list = new ArrayList(); + list.add(1); + list.add(1); + + int i = 0; + while (true) { + int num = (int) list.get(i) + (int) list.get(i + 1); + if (num < max) { + list.add(num); + } else { + break; + } + i++; + } + + return intListToArray(list); + } + + private int[] intListToArray(List list) { + int[] array = new int[list.size()]; + for (int i = 0; i < list.size(); i++) { + array[i] = (int) list.get(i); + } + return array; + } + + /** + * 返回小于给定最大值max的所有素数数组 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * + * @param max + * @return + */ + public int[] getPrimes(int max) { + if (max < 0) { + throw new IllegalArgumentException(); + } + + ArrayList list = new ArrayList(); + for (int i = 2; i < max; i++) { + if (isPrime(i)) { + list.add(i); + } + } + return intListToArray(list); + } + + private boolean isPrime(int num) { + for (int i = 2; i <= num / 2; i++) { + if (num % i == 0) { + return false; + } + } + return true; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * + * @param max + * @return + */ + public int[] getPerfectNumbers(int max) { + if (max < 0) { + throw new IllegalArgumentException(); + } + + ArrayList list = new ArrayList(); + for (int i = 2; i < max; i++) { + if (isPerfectNumber(i)) { + list.add(i); + } + } + return intListToArray(list); + } + + private boolean isPerfectNumber(int num) { + int sumOfFactor = 1; + for (int i = 2; i <= num / 2; i++) { + if (num % i == 0) { + sumOfFactor += i; + } + } + if (sumOfFactor == 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) { + if (array == null) { + throw new IllegalArgumentException(); + } + if (array.length == 0) { + return ""; + } + + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < array.length; i++) { + builder.append(array[i]).append(seperator); + } + return builder.substring(0, builder.length() - seperator.length()); + } + + +} diff --git a/group01/765324639/src/main/java/datastructure/linkedlist/LRUPageFrame.java b/group01/765324639/src/main/java/datastructure/linkedlist/LRUPageFrame.java new file mode 100644 index 0000000000..cc4771562d --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/linkedlist/LRUPageFrame.java @@ -0,0 +1,177 @@ +package datastructure.linkedlist; + +/** + * 用双向链表实现LRU算法 + * + * @author liuxin + * + */ +public class LRUPageFrame { + + private static class Node { + Node prev; + Node next; + int pageNum; + + Node(int pageNum) { + this.pageNum = pageNum; + } + } + + private int capacity; + private int size; + + private Node first;// 链表头 + private Node last;// 链表尾 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + if (isEmpty()) { + initFirstNode(pageNum); + return; + } + + if (contains(pageNum)) { + moveToFirst(pageNum); + } else { + insert(pageNum); + } + } + + private void initFirstNode(int pageNum) { + Node node = new Node(pageNum); + first = last = node; + size++; + } + + private void moveToFirst(int pageNum) { + if (isFirst(pageNum)) { + return; + } + if (isLast(pageNum)) { + moveLastToFirst(); + } else { + moveMidToFirst(pageNum); + } + } + + private void moveLastToFirst() { + Node temp = last; + + removeLast(); + + addToFirst(temp); + } + + private void addToFirst(Node temp) { + temp.next = first; + first.prev = temp; + first = temp; + size++; + } + + private void moveMidToFirst(int pageNum) { + Node node = removeMidNode(pageNum); + addToFirst(node); + } + + private Node removeMidNode(int pageNum) { + Node temp = getNode(pageNum); + temp.prev.next = temp.next; + temp.next.prev = temp.prev; + + temp.next = null; + temp.prev = null; + + size--; + + return temp; + } + + private void insert(int pageNum) { + if (isFill()) { + removeLast(); + } + insertToFirst(pageNum); + } + + private void removeLast() { + last = last.prev; + last.next = null; + size--; + } + + private void insertToFirst(int pageNum) { + Node node = new Node(pageNum); + + addToFirst(node); + } + + private boolean contains(int pageNum) { + return indexOf(pageNum) != -1; + } + + private int indexOf(int num) { + Node temp = first; + for (int i = 0; i < size; i++) { + if (temp.pageNum == num) { + return i; + } + temp = temp.next; + } + return -1; + } + + private Node getNode(int pageNum) { + Node temp; + temp = first; + for (int i = 0; i < size; i++) { + if (temp.pageNum == pageNum) { + break; + } + temp = temp.next; + } + return temp; + } + + private boolean isEmpty() { + return size == 0; + } + + private boolean isFirst(int pageNum) { + return first.pageNum == pageNum; + } + + private boolean isLast(int pageNum) { + return last.pageNum == pageNum; + } + + private boolean isFill() { + return size == capacity; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + Node node = first; + while (node != null) { + buffer.append(node.pageNum); + + node = node.next; + if (node != null) { + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group01/765324639/src/main/java/datastructure/linkedlist/LinkedList.java b/group01/765324639/src/main/java/datastructure/linkedlist/LinkedList.java new file mode 100644 index 0000000000..acdb3320d9 --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/linkedlist/LinkedList.java @@ -0,0 +1,378 @@ +package datastructure.linkedlist; + +import java.util.NoSuchElementException; + +import datastructure.Iterator; +import datastructure.List; + +public class LinkedList implements List { + + private Node head; + + private int size = 0; + + @Override + public void add(Object o) { + if (head == null) { + head = new Node(o); + } else { + Node tail = head; + while (tail.next != null) { + tail = tail.next; + } + Node node = new Node(o); + + tail.next = node; + } + size++; + } + + @Override + public void add(int index, Object o) { + rangeCheckForAdd(index); + if (index == 0) { + Node node = new Node(o); + node.next = head; + head = node; + } else { + Node preDest = head; + for (int i = 0; i < index - 1; i++) { + preDest = preDest.next; + } + Node node = new Node(o); + node.next = preDest.next; + preDest.next = node; + } + + size++; + } + + private void rangeCheckForAdd(int index) { + if (index > size || index < 0) { + throw new IndexOutOfBoundsException(); + } + } + + @Override + public Object get(int index) { + rangeCheck(index); + + Node dest = head; + for (int i = 0; i < index; i++) { + dest = dest.next; + } + return dest.data; + } + + private void rangeCheck(int index) { + if (index >= size || index < 0) { + throw new IndexOutOfBoundsException(); + } + } + + @Override + public Object remove(int index) { + rangeCheck(index); + + Node preDest = head; + for (int i = 0; i < index - 1; i++) { + preDest = preDest.next; + } + Node dest = preDest.next; + preDest.next = dest.next; + + size--; + return dest.data; + } + + @Override + public int size() { + return size; + } + + public void addFirst(Object o) { + Node node = new Node(o); + node.next = head; + head = node; + size++; + } + + public void addLast(Object o) { + Node lastNode = head; + while (lastNode.next != null) { + lastNode = lastNode.next; + } + + Node node = new Node(o); + lastNode.next = node; + size++; + } + + public Object removeFirst() { + if (head == null) { + throw new NoSuchElementException(); + } + Node target = head; + head = head.next; + size--; + return target.data; + } + + public Object removeLast() { + if (head == null) { + throw new NoSuchElementException(); + } + + Node preDest = head; + while (preDest.next.next != null) { + preDest = preDest.next; + } + Node dest = preDest.next; + preDest.next = null; + + size--; + return dest.data; + } + + public Iterator iterator() { + return null; + } + + + private static class Node { + Object data; + Node next; + + Node(Object data) { + this.data = data; + next = null; + } + } + + // =========================第三周作业========================= + + /** + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + Node reverseNode = null; + while (head != null) { + Node temp = head; + head = head.next; + temp.next = reverseNode; + reverseNode = temp; + } + head = reverseNode; + } + + /** + * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf() { + int newStartIndex = size / 2; + for (int i = 0; i < newStartIndex; i++) { + head = head.next; + } + size = size - newStartIndex; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + if (i < 0) { + throw new IllegalArgumentException(); + } + if (i + length >= size) { + length = size - i; + } + + if (i == 0) { + for (int j = 0; j < length; j++) { + head = head.next; + } + } else { + Node beforeRemoveStartNode = head; + for (int j = 0; j < i - 1; j++) { + beforeRemoveStartNode = beforeRemoveStartNode.next; + } + + Node removeEndNode = beforeRemoveStartNode; + for (int j = 0; j < length; j++) { + removeEndNode = removeEndNode.next; + } + + beforeRemoveStartNode.next = removeEndNode.next; + } + + size = size - length; + } + + /** + * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 返回的结果应该是[101,301,401,601] + * + * @param list + */ + public int[] getElements(LinkedList list) { + checkList(list); + + int[] dest = new int[list.size]; + int arrayNum = 0; + Node temp = head; + int n = (int) list.get(0); + for (int i = 0; i < n; i++) { + temp = temp.next; + } + dest[arrayNum++] = (int) temp.data; + + for (int i = 1; i < list.size; i++) { + int num = (int) list.get(i) - (int) list.get(i - 1); + for (int j = 0; j < num; j++) { + temp = temp.next; + } + dest[arrayNum++] = (int) temp.data; + } + return dest; + } + + private void checkList(LinkedList list) { + for (int i = 0; i < list.size; i++) { + if ((int) list.get(i) < 0 || (int) list.get(i) >= size) { + throw new IllegalArgumentException("list中的元素位置越界"); + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 + * + * @param list + */ + + public void subtract(LinkedList list) { + if (list == null || list.size == 0 || this.size == 0) { + return; + } + + int thisIndex = 0; + int listIndex = 0; + Node temp = head; + while (true) { // 后续需要优化替换remove()方法 + if ((int) temp.data < (int) list.get(listIndex)) { + temp = temp.next; + thisIndex++; + } else if ((int) temp.data == (int) list.get(listIndex)) { + this.remove(thisIndex); + temp = temp.next; + thisIndex++; + listIndex++; + } else { + listIndex++; + } + + if (thisIndex >= this.size || listIndex >= list.size) { + break; + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + if (this.size == 0) { + return; + } + + Node subHead = head; + Node subTail = head; + + while (true) { + if (subTail == null) { + subHead.next = null; // 清除尾部重复的元素 + break; + } + if ((int) subTail.data == (int) subHead.data) { + if (!(subTail == subHead)) { // 判断两个指针是否指向同一个地方 + this.size--; + } + subTail = subTail.next; + } else { + subHead.next = subTail; + subHead = subHead.next; + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + public void removeRange(int min, int max) { + if (this.size == 0) { + return; + } + + if ((int) head.data > max) { + throw new IllegalArgumentException(); + } + + int length = 0; + Node subList = new Node(null); + Node temp = subList; + while (true) { + if (head == null) { + break; + } + if ((int) head.data <= min || (int) head.data >= max) { + temp.next = head; + temp = temp.next; + length++; + } + head = head.next; + } + temp.next = null; // 去掉尾部多余数据 + head = subList.next; + size = length; + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * + * @param list + */ + public LinkedList intersection(LinkedList list) { + if (this.size == 0 || list.size == 0) { + return null; + } + + Node tempHead = head; + int listIndex = 0; + + LinkedList newList = new LinkedList(); + while (true) { + if (tempHead == null || listIndex >= list.size) { + break; + } + + if ((int) tempHead.data < (int) list.get(listIndex)) { + tempHead = tempHead.next; + } else if ((int) tempHead.data > (int) list.get(listIndex)) { + listIndex++; + } else { + newList.add(tempHead.data); + + tempHead = tempHead.next; + listIndex++; + } + } + + return newList; + } +} diff --git a/group01/765324639/src/main/java/datastructure/stack/Stack.java b/group01/765324639/src/main/java/datastructure/stack/Stack.java new file mode 100644 index 0000000000..52d4f818e8 --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/stack/Stack.java @@ -0,0 +1,47 @@ +package datastructure.stack; + +import java.util.EmptyStackException; + +import datastructure.array.ArrayList; + +public class Stack { + private ArrayList elementData = new ArrayList(); + + public void push(Object o) { + elementData.add(o); + } + + public Object pop() { + if (elementData.size() == 0) { + throw new EmptyStackException(); + } + return elementData.remove(elementData.size() - 1); + } + + public Object peek() { + if (elementData.size() == 0) { + throw new EmptyStackException(); + } + return elementData.get(elementData.size() - 1); + } + + public boolean isEmpty() { + return elementData.size() == 0; + } + + public int size() { + return elementData.size(); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + int i = 0; + for ( ; i < elementData.size() - 1; i++) { + builder.append(elementData.get(i) + ","); + } + builder.append(elementData.get(i)); + return builder.toString(); + } + +} diff --git a/group01/765324639/src/main/java/datastructure/stack/StackUtil.java b/group01/765324639/src/main/java/datastructure/stack/StackUtil.java new file mode 100644 index 0000000000..b45f90337d --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/stack/StackUtil.java @@ -0,0 +1,110 @@ +package datastructure.stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if (s == null || s.isEmpty()) { + return; + } + + Stack temp1 = new Stack(); + while (!s.isEmpty()) { + temp1.push(s.pop()); + } + Stack temp2 = new Stack(); + while (!temp1.isEmpty()) { + temp2.push(temp1.pop()); + } + while (!temp2.isEmpty()) { + s.push(temp2.pop()); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if (s == null || s.isEmpty()) { + return; + } + + Stack temp = new Stack(); + while (!s.isEmpty()) { + int num = (int) s.pop(); + if (num != (int)o) { + temp.push(num); + } + } + while (!temp.isEmpty()) { + s.push(temp.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if (s == null || s.isEmpty() || len < 0) { + return null; + } + + Stack temp = new Stack(); + int i = 0; + Object[] obj = new Object[len]; + while(!s.isEmpty() && i < len) { + temp.push(s.peek()); + obj[i++] = s.pop(); + } + while (!temp.isEmpty()) { + s.push(temp.pop()); + } + return obj; + } + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + if (s == null) { + return false; + } + + Stack stack = new Stack(); + char[] charArray = s.toCharArray(); + for (int i = 0; i < charArray.length; i++) { + char c = charArray[i]; + if (c == '(' || c == '[' || c == '{') { + stack.push(c); + } else if (c == ')') { + if ('(' != (char)stack.pop()) { + return false; + } + } else if (c == ']') { + if ('[' != (char)stack.pop()) { + return false; + } + } else if (c == '}') { + if ('{' != (char)stack.pop()) { + return false; + } + } + } + return true; + } + + +} diff --git a/group01/765324639/src/main/java/datastructure/stack/expr/InfixExpr.java b/group01/765324639/src/main/java/datastructure/stack/expr/InfixExpr.java new file mode 100644 index 0000000000..febd242e75 --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/stack/expr/InfixExpr.java @@ -0,0 +1,75 @@ +package datastructure.stack.expr; + +import java.util.List; +import java.util.Stack; + +public class InfixExpr { + String expr = null; + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + TokenParser tokenParser = new TokenParser(expr); + List tokenList = tokenParser.parse(); + + Stack operaStack = new Stack<>(); + Stack floatStack = new Stack<>(); + + for (int i = 0; i < tokenList.size(); i++) { + if (Token.OPERATOR.equals(tokenList.get(i).getType())) { + if (operaStack.isEmpty()) { + operaStack.push(tokenList.get(i)); + } else { + Token topToken = operaStack.peek(); + if (tokenList.get(i).comparePriority(topToken) > 0) { + operaStack.push(tokenList.get(i)); + } else { + float result = stackTopCalculate(operaStack, floatStack); + floatStack.push(result); + + i--; + } + } + } else { + floatStack.push(Float.valueOf(tokenList.get(i).getValue())); + } + } + while (!operaStack.empty()) { + float temp = stackTopCalculate(operaStack, floatStack); + floatStack.push(temp); + } + return floatStack.pop(); + } + + private float stackTopCalculate(Stack operaStack, Stack floatStack) { + String operator = operaStack.pop().getValue(); + float num2 = floatStack.pop(); + float num1 = floatStack.pop(); + float result = calculate(operator, num1, num2); + return result; + } + + private float calculate(String operator, float num1, float num2) { + float result = 0; + switch (operator.charAt(0)) { + case '+': + result = num1 + num2; + break; + case '-': + result = num1 - num2; + break; + case '*': + result = num1 * num2; + break; + case '/': + result = num1 / num2; + break; + default: + throw new IllegalArgumentException(); + } + return result; + } + +} diff --git a/group01/765324639/src/main/java/datastructure/stack/expr/Token.java b/group01/765324639/src/main/java/datastructure/stack/expr/Token.java new file mode 100644 index 0000000000..44a019197d --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/stack/expr/Token.java @@ -0,0 +1,51 @@ +package datastructure.stack.expr; + +public class Token { + + public static final String NUMBER = "number"; + + public static final String OPERATOR = "operator"; + + private String type; + + private String value; + + public Token(String type, String value) { + this.type = type; + this.value = value; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public int comparePriority(Token token) { + String higherLevel = "*/"; + String lowerLevel = "+-"; + if (higherLevel.contains(token.getValue())) { + if (higherLevel.contains(this.value)) { + return 0; + } + return -1; + } else if (lowerLevel.contains(token.getValue())){ + if (lowerLevel.contains(this.value)) { + return 0; + } + return 1; + } else { + throw new RuntimeException("不支持的运算符"); + } + } +} diff --git a/group01/765324639/src/main/java/datastructure/stack/expr/TokenParser.java b/group01/765324639/src/main/java/datastructure/stack/expr/TokenParser.java new file mode 100644 index 0000000000..e1add57663 --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/stack/expr/TokenParser.java @@ -0,0 +1,66 @@ +package datastructure.stack.expr; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class TokenParser { + + private String expr; + + private List tokenList = new ArrayList<>(); + + public TokenParser(String expr) { + this.expr = expr; + } + + public List parse() { + if (expr == null || "".equals(expr)) { + return Collections.emptyList(); + } + + char[] charArray = expr.toCharArray(); + for (int i = 0; i < charArray.length; i++) { + if (isNumber(charArray[i])) { + i = addFullNumber(charArray, i); + i--; + } else if (isOperator(charArray[i])) { + addOperator(charArray[i]); + } + } + return tokenList; + } + + private boolean isNumber(char c) { + String numbers = "0123456789"; + if (numbers.indexOf(c) != -1) { + return true; + } + return false; + } + + private boolean isOperator(char c) { + String supplyOperator = "+-*/"; + if (supplyOperator.indexOf(supplyOperator) != -1) { + return true; + } + return false; + } + + private int addFullNumber(char[] charArray, int i) { + StringBuilder builder = new StringBuilder(); + for (; i < charArray.length; i++) { + if (isNumber(charArray[i])) { + builder.append(charArray[i]); + } else { + break; + } + } + tokenList.add(new Token(Token.NUMBER, builder.toString())); + return i; + } + + private void addOperator(char c) { + tokenList.add(new Token(Token.OPERATOR, String.valueOf(c))); + } +} diff --git a/group01/765324639/src/main/java/download/DownloadThread.java b/group01/765324639/src/main/java/download/DownloadThread.java new file mode 100644 index 0000000000..88641b3741 --- /dev/null +++ b/group01/765324639/src/main/java/download/DownloadThread.java @@ -0,0 +1,45 @@ +package download; + +import java.io.IOException; +import java.io.RandomAccessFile; + +import download.api.Connection; + +public class DownloadThread extends Thread { + + Connection conn; + int startPos; + int endPos; + + + public DownloadThread(Connection conn, int startPos, int endPos) { + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + + } + + @Override + public void run() { + System.out.println("start download:" + startPos + "~" + endPos); + byte[] data = new byte[endPos - startPos]; + try { + data = conn.read(startPos, endPos); + } catch (IOException e) { + e.printStackTrace(); + } + writeToFile(data); + } + + private void writeToFile(byte[] data) { + RandomAccessFile file; + try { + file = new RandomAccessFile("download20170311.jpg", "rw"); + file.seek(startPos); + file.write(data, 0, data.length); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/group01/765324639/src/main/java/download/FileDownloader.java b/group01/765324639/src/main/java/download/FileDownloader.java new file mode 100644 index 0000000000..91f972db71 --- /dev/null +++ b/group01/765324639/src/main/java/download/FileDownloader.java @@ -0,0 +1,100 @@ +package download; + +import java.io.IOException; +import java.io.RandomAccessFile; + +import download.api.Connection; +import download.api.ConnectionException; +import download.api.ConnectionManager; +import download.api.DownloadListener; + + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute() { + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection conn = null; + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + createPlaceHolderFile("download20170311.jpg", length); + + DownloadThread downloadThread1 = new DownloadThread(cm.open(this.url), 0, length / 3); + downloadThread1.start(); + DownloadThread downloadThread2 = + new DownloadThread(cm.open(this.url), length / 3 + 1, length / 3 * 2); + downloadThread2.start(); + DownloadThread downloadThread3 = + new DownloadThread(cm.open(this.url), length / 3 * 2 + 1, length - 1); + downloadThread3.start(); + try { + downloadThread1.join(); + downloadThread2.join(); + downloadThread3.join(); + listener.notifyFinished(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } catch (ConnectionException e) { + e.printStackTrace(); + } catch (IOException e1) { + e1.printStackTrace(); + } finally { + if (conn != null) { + conn.close(); + } + } + + } + + private void createPlaceHolderFile(String fileName, int contentLen) throws IOException { + + RandomAccessFile file = new RandomAccessFile(fileName, "rw"); + + for (int i = 0; i < contentLen; i++) { + file.write(0); + } + + file.close(); + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm) { + this.cm = ucm; + } + + public DownloadListener getListener() { + return this.listener; + } + +} diff --git a/group01/765324639/src/main/java/download/api/Connection.java b/group01/765324639/src/main/java/download/api/Connection.java new file mode 100644 index 0000000000..c0c2a33285 --- /dev/null +++ b/group01/765324639/src/main/java/download/api/Connection.java @@ -0,0 +1,26 @@ +package download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos, int endPos) throws IOException; + + /** + * 得到数据内容的长度 + * + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group01/765324639/src/main/java/download/api/ConnectionException.java b/group01/765324639/src/main/java/download/api/ConnectionException.java new file mode 100644 index 0000000000..9daefa720f --- /dev/null +++ b/group01/765324639/src/main/java/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group01/765324639/src/main/java/download/api/ConnectionManager.java b/group01/765324639/src/main/java/download/api/ConnectionManager.java new file mode 100644 index 0000000000..c74bf0d41f --- /dev/null +++ b/group01/765324639/src/main/java/download/api/ConnectionManager.java @@ -0,0 +1,11 @@ +package download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group01/765324639/src/main/java/download/api/DownloadListener.java b/group01/765324639/src/main/java/download/api/DownloadListener.java new file mode 100644 index 0000000000..f3730b32a1 --- /dev/null +++ b/group01/765324639/src/main/java/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group01/765324639/src/main/java/download/impl/ConnectionImpl.java b/group01/765324639/src/main/java/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..634fd6f1df --- /dev/null +++ b/group01/765324639/src/main/java/download/impl/ConnectionImpl.java @@ -0,0 +1,62 @@ +package download.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import download.api.Connection; + +public class ConnectionImpl implements Connection { + + private URL url = null;; + + private HttpURLConnection conn = null; + + public ConnectionImpl(String url) { + try { + this.url = new URL(url); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + try { + conn = (HttpURLConnection) url.openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + InputStream inputStream = conn.getInputStream(); + byte[] result = new byte[endPos - startPos + 1]; + byte[] data = new byte[1024]; + int read = -1; + int i = 0; + while ((read = inputStream.read(data, 0, data.length)) != -1) { + System.arraycopy(data, 0, result, i, read); + i += read; + } + return result; + } + + @Override + public int getContentLength() { + HttpURLConnection openConnection = null; + try { + openConnection = (HttpURLConnection) url.openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + int contentLength = openConnection.getContentLength(); + openConnection.disconnect(); + return contentLength; + } + + @Override + public void close() { + } + +} diff --git a/group01/765324639/src/main/java/download/impl/ConnectionManagerImpl.java b/group01/765324639/src/main/java/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..9663736f21 --- /dev/null +++ b/group01/765324639/src/main/java/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,14 @@ +package download.impl; + +import download.api.Connection; +import download.api.ConnectionException; +import download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + +} diff --git a/group01/765324639/src/main/java/litestruts/LoginAction.java b/group01/765324639/src/main/java/litestruts/LoginAction.java new file mode 100644 index 0000000000..87ae0c4fcf --- /dev/null +++ b/group01/765324639/src/main/java/litestruts/LoginAction.java @@ -0,0 +1,42 @@ +package 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/765324639/src/main/java/litestruts/Struts.java b/group01/765324639/src/main/java/litestruts/Struts.java new file mode 100644 index 0000000000..5230e424e2 --- /dev/null +++ b/group01/765324639/src/main/java/litestruts/Struts.java @@ -0,0 +1,117 @@ +package litestruts; + +import java.io.InputStream; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + + + +public class Struts { + + public static 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 { + + SAXReader reader = new SAXReader(); + InputStream struts = Struts.class.getResourceAsStream("struts.xml"); + Document document = null; + try { + document = reader.read(struts); + } catch (DocumentException e) { + e.printStackTrace(); + } + + String className = ""; // actionName对应的类名 + Element rootElement = document.getRootElement(); + Iterator iterator = rootElement.elementIterator("action"); + Element targetAction = null; // actionName对应的action + while (iterator.hasNext()) { + Element element = (Element) iterator.next(); + String name = element.attributeValue("name"); + if (name.equals(actionName)) { + className = element.attributeValue("class"); + targetAction = element; + break; + } + } + + + Class class1 = Class.forName(className); + Object instance = class1.newInstance(); + + Set keySet = parameters.keySet(); + for (String key : keySet) { + // 将变量名拼成对应的set方法名 + String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); + Class type = class1.getDeclaredField(key).getType(); + Method method = class1.getDeclaredMethod(methodName, type); + // 依次调用对应的set方法 + method.invoke(instance, parameters.get(key)); + } + + String result = (String) class1.getDeclaredMethod("execute").invoke(instance); + + Method[] declaredMethods = class1.getDeclaredMethods(); + HashMap map = new HashMap<>(); + for (int i = 0; i < declaredMethods.length; i++) { + if (declaredMethods[i].getName().startsWith("get")) { + String fieldValue = (String) declaredMethods[i].invoke(instance); + String fieldName = methodNameToFieldName(declaredMethods[i].getName()); + map.put(fieldName, fieldValue); + } + } + + View view = new View(); + view.setParameters(map); + + Iterator elementIterator = targetAction.elementIterator("result"); + while (elementIterator.hasNext()) { + Element element = (Element) elementIterator.next(); + if (result.equals(element.attributeValue("name"))) { + view.setJsp(element.getText()); + } + } + + return view; + + + } catch (Exception e1) { + e1.printStackTrace(); + } + + return null; + } + + private static String methodNameToFieldName(String methodName) { + if (!methodName.startsWith("get") && !methodName.startsWith("set")) { + throw new IllegalArgumentException(); + } + + return methodName.substring(3, 4).toLowerCase() + methodName.substring(4); + } + +} diff --git a/group01/765324639/src/main/java/litestruts/View.java b/group01/765324639/src/main/java/litestruts/View.java new file mode 100644 index 0000000000..4a553757d0 --- /dev/null +++ b/group01/765324639/src/main/java/litestruts/View.java @@ -0,0 +1,26 @@ +package litestruts; + +import java.util.Map; + +public class View { + private String jsp; + private Map parameters; + + public String getJsp() { + return jsp; + } + + public View setJsp(String jsp) { + this.jsp = jsp; + return this; + } + + public Map getParameters() { + return parameters; + } + + public View setParameters(Map parameters) { + this.parameters = parameters; + return this; + } +} diff --git a/group01/765324639/src/main/java/litestruts/struts.xml b/group01/765324639/src/main/java/litestruts/struts.xml new file mode 100644 index 0000000000..a7eccffd9c --- /dev/null +++ b/group01/765324639/src/main/java/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/765324639/src/main/java/minijvm/attr/AttributeInfo.java b/group01/765324639/src/main/java/minijvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..fc261d7eff --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/attr/AttributeInfo.java @@ -0,0 +1,19 @@ +package minijvm.attr; + +public abstract class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + int attrNameIndex; + int attrLen ; + public AttributeInfo(int attrNameIndex, int attrLen) { + + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } + + +} diff --git a/group01/765324639/src/main/java/minijvm/attr/CodeAttr.java b/group01/765324639/src/main/java/minijvm/attr/CodeAttr.java new file mode 100644 index 0000000000..0044adced8 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/attr/CodeAttr.java @@ -0,0 +1,55 @@ +package minijvm.attr; + +import minijvm.clz.ClassFile; +import minijvm.loader.ByteCodeIterator; + + +public class CodeAttr extends AttributeInfo { + private int maxStack ; + private int maxLocals ; + private int codeLen ; + private String code; + public String getCode() { + return code; + } + + //private ByteCodeCommand[] cmds ; + //public ByteCodeCommand[] getCmds() { + // return cmds; + //} + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + //this.cmds = cmds; + } + + public void setLineNumberTable(LineNumberTable t) { + this.lineNumTable = t; + } + + public void setLocalVariableTable(LocalVariableTable t) { + this.localVarTable = t; + } + + public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ + + + return null; + } + private void setStackMapTable(StackMapTable t) { + this.stackMapTable = t; + + } + + + + + +} diff --git a/group01/765324639/src/main/java/minijvm/attr/LineNumberTable.java b/group01/765324639/src/main/java/minijvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..71a44fd83e --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/attr/LineNumberTable.java @@ -0,0 +1,42 @@ +package minijvm.attr; + +import java.util.ArrayList; +import java.util.List; + +import minijvm.loader.ByteCodeIterator; + +public class LineNumberTable extends AttributeInfo { + List items = new ArrayList(); + + private static class LineNumberItem{ + int startPC; + int lineNum; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + public void addLineNumberItem(LineNumberItem item){ + this.items.add(item); + } + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + + } + + public static LineNumberTable parse(ByteCodeIterator iter){ + + return null; + } + + + +} diff --git a/group01/765324639/src/main/java/minijvm/attr/LocalVariableItem.java b/group01/765324639/src/main/java/minijvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..7953b04d23 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/attr/LocalVariableItem.java @@ -0,0 +1,39 @@ +package minijvm.attr; + +public class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getNameIndex() { + return nameIndex; + } + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + public int getDescIndex() { + return descIndex; + } + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } +} diff --git a/group01/765324639/src/main/java/minijvm/attr/LocalVariableTable.java b/group01/765324639/src/main/java/minijvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..90248d54f4 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/attr/LocalVariableTable.java @@ -0,0 +1,26 @@ +package minijvm.attr; + + +import java.util.ArrayList; +import java.util.List; + +import minijvm.loader.ByteCodeIterator; + +public class LocalVariableTable extends AttributeInfo{ + + List items = new ArrayList(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LocalVariableTable parse(ByteCodeIterator iter){ + + return null; + } + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + + +} diff --git a/group01/765324639/src/main/java/minijvm/attr/StackMapTable.java b/group01/765324639/src/main/java/minijvm/attr/StackMapTable.java new file mode 100644 index 0000000000..7ed27a16a5 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/attr/StackMapTable.java @@ -0,0 +1,30 @@ +package minijvm.attr; + + +import minijvm.loader.ByteCodeIterator; + +public class StackMapTable extends AttributeInfo{ + + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.nextU2ToInt(); + int len = iter.nextU4ToInt(); + StackMapTable t = new StackMapTable(index,len); + + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + String code = iter.nextUxToHexString(len); + t.setOriginalCode(code); + + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} diff --git a/group01/765324639/src/main/java/minijvm/clz/AccessFlag.java b/group01/765324639/src/main/java/minijvm/clz/AccessFlag.java new file mode 100644 index 0000000000..7585a3c460 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package minijvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group01/765324639/src/main/java/minijvm/clz/ClassFile.java b/group01/765324639/src/main/java/minijvm/clz/ClassFile.java new file mode 100644 index 0000000000..d1cdbe0e05 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/clz/ClassFile.java @@ -0,0 +1,92 @@ +package minijvm.clz; + +import java.util.ArrayList; +import java.util.List; + +import minijvm.constant.ClassInfo; +import minijvm.constant.ConstantPool; +import minijvm.field.Field; +import minijvm.method.Method; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + private List fields = new ArrayList(); + private List methods = new ArrayList(); + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + public void addField(Field f){ + this.fields.add(f); + } + public List getFields(){ + return this.fields; + } + public void addMethod(Method m){ + this.methods.add(m); + } + public List getMethods() { + return methods; + } + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + + System.out.println("Super Class Name:"+ getSuperClassName()); + + + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group01/765324639/src/main/java/minijvm/clz/ClassIndex.java b/group01/765324639/src/main/java/minijvm/clz/ClassIndex.java new file mode 100644 index 0000000000..4b25095924 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package minijvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group01/765324639/src/main/java/minijvm/constant/ClassInfo.java b/group01/765324639/src/main/java/minijvm/constant/ClassInfo.java new file mode 100644 index 0000000000..c856052998 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/ClassInfo.java @@ -0,0 +1,25 @@ +package minijvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index ; + public ClassInfo(ConstantPool pool) { + super(pool); + } + public int getUtf8Index() { + return utf8Index; + } + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + @Override + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group01/765324639/src/main/java/minijvm/constant/ConstantInfo.java b/group01/765324639/src/main/java/minijvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..5fa0be0189 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package minijvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group01/765324639/src/main/java/minijvm/constant/ConstantPool.java b/group01/765324639/src/main/java/minijvm/constant/ConstantPool.java new file mode 100644 index 0000000000..12746a1f3c --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package minijvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group01/765324639/src/main/java/minijvm/constant/FieldRefInfo.java b/group01/765324639/src/main/java/minijvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..ddcf2df456 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/FieldRefInfo.java @@ -0,0 +1,56 @@ +package minijvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + @Override + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group01/765324639/src/main/java/minijvm/constant/MethodRefInfo.java b/group01/765324639/src/main/java/minijvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..f4c2368228 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/MethodRefInfo.java @@ -0,0 +1,57 @@ +package minijvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + @Override + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group01/765324639/src/main/java/minijvm/constant/NameAndTypeInfo.java b/group01/765324639/src/main/java/minijvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..de88422d82 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/NameAndTypeInfo.java @@ -0,0 +1,47 @@ +package minijvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + @Override + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + @Override + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group01/765324639/src/main/java/minijvm/constant/NullConstantInfo.java b/group01/765324639/src/main/java/minijvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..88eb702f4b --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package minijvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group01/765324639/src/main/java/minijvm/constant/StringInfo.java b/group01/765324639/src/main/java/minijvm/constant/StringInfo.java new file mode 100644 index 0000000000..915652a93c --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/StringInfo.java @@ -0,0 +1,28 @@ +package minijvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index; + public StringInfo(ConstantPool pool) { + super(pool); + } + + @Override + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + @Override + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group01/765324639/src/main/java/minijvm/constant/UTF8Info.java b/group01/765324639/src/main/java/minijvm/constant/UTF8Info.java new file mode 100644 index 0000000000..1af71e8e9c --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/UTF8Info.java @@ -0,0 +1,33 @@ +package minijvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + @Override + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group01/765324639/src/main/java/minijvm/field/Field.java b/group01/765324639/src/main/java/minijvm/field/Field.java new file mode 100644 index 0000000000..85fded5380 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/field/Field.java @@ -0,0 +1,39 @@ +package minijvm.field; + +import minijvm.constant.ConstantPool; +import minijvm.constant.UTF8Info; +import minijvm.loader.ByteCodeIterator; + + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + + + private ConstantPool pool; + + public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + + + public static Field parse(ConstantPool pool,ByteCodeIterator iter){ + + return null; + } + + @Override + public String toString() { + String fieldName = ((UTF8Info)pool.getConstantInfo(nameIndex)).getValue(); + String fieldDescription = ((UTF8Info)pool.getConstantInfo(descriptorIndex)).getValue(); + return fieldName + ":" + fieldDescription; + } +} diff --git a/group01/765324639/src/main/java/minijvm/loader/ByteCodeIterator.java b/group01/765324639/src/main/java/minijvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..bcfbbace77 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/loader/ByteCodeIterator.java @@ -0,0 +1,65 @@ +package minijvm.loader; + +import java.io.UnsupportedEncodingException; + +import minijvm.util.Util; + +public class ByteCodeIterator { + + private byte[] codes; + + private int pos = 0; + + public ByteCodeIterator (byte[] codes) { + this.codes = codes; + } + + public int nextU1ToInt() { + return Util.byteToInt(new byte[]{codes[pos++]}); + } + + public int nextU2ToInt() { + return Util.byteToInt(new byte[]{codes[pos++], codes[pos++]}); + } + + public int nextU4ToInt() { + return Util.byteToInt(new byte[]{codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextU4ToHexString() { + return Util.byteToHexString(new byte[]{codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextUxToHexString(int length) { + byte[] src = new byte[length]; + for (int i = 0; i < length; i++) { + src[i] = codes[pos++]; + } + return Util.byteToHexString(src); + } + + public String nextLengthToString(int length) { + String dest = null; + try { + dest = new String(getBytes(length), "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return dest; + } + + public void back(int length) { + for (int i = 0; i < length; i++) { + pos--; + } + } + + private byte[] getBytes(int length) { + byte[] b = new byte[length]; + for (int i = 0; i < length; i++) { + b[i] = codes[pos++]; + } + return b; + } + +} diff --git a/group01/765324639/src/main/java/minijvm/loader/ClassFileLoader.java b/group01/765324639/src/main/java/minijvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..51bce28f2a --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/loader/ClassFileLoader.java @@ -0,0 +1,80 @@ +package minijvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import minijvm.clz.ClassFile; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws ClassNotFoundException { + File classFile = getClassFile(className); + return readFileToByteArray(classFile); + } + + private File getClassFile(String className) throws ClassNotFoundException { + File classFile = null; + String classFilePath = convertClassNameToFilePath(className); + for (String path : clzPaths) { + File file = new File(path, classFilePath); + if (file.exists()) { + classFile = file; + break; + } + } + + if (classFile == null) { // 文件不存在 + throw new ClassNotFoundException(); + } + return classFile; + } + + private byte[] readFileToByteArray(File classFile) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (InputStream in = new FileInputStream(classFile);) { + byte[] data = new byte[1024]; + int len = -1; + while ((len = in.read(data)) != -1) { + out.write(data, 0, len); + } + } catch (FileNotFoundException e) { // 调用此函数时,已经确定文件是存在的 + e.printStackTrace(); + } catch (IOException e1) { + e1.printStackTrace(); + } + return out.toByteArray(); + } + + private String convertClassNameToFilePath(String fillClassName) { + return fillClassName.replace(".", File.separator) + ".class"; + } + + public void addClassPath(String path) { + if (clzPaths.contains(path)) { + return; + } + clzPaths.add(path); + } + + public String getClassPath() { + return String.join(";", clzPaths); + } + + public ClassFile loadClass(String className) throws ClassNotFoundException { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + +} diff --git a/group01/765324639/src/main/java/minijvm/loader/ClassFileParser.java b/group01/765324639/src/main/java/minijvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..cb42be22d6 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/loader/ClassFileParser.java @@ -0,0 +1,257 @@ +package minijvm.loader; + +import java.util.ArrayList; +import java.util.List; + +import minijvm.attr.AttributeInfo; +import minijvm.attr.CodeAttr; +import minijvm.attr.LineNumberTable; +import minijvm.attr.LocalVariableTable; +import minijvm.clz.AccessFlag; +import minijvm.clz.ClassFile; +import minijvm.clz.ClassIndex; +import minijvm.constant.ClassInfo; +import minijvm.constant.ConstantInfo; +import minijvm.constant.ConstantPool; +import minijvm.constant.FieldRefInfo; +import minijvm.constant.MethodRefInfo; +import minijvm.constant.NameAndTypeInfo; +import minijvm.constant.NullConstantInfo; +import minijvm.constant.StringInfo; +import minijvm.constant.UTF8Info; +import minijvm.field.Field; +import minijvm.method.Method; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + ByteCodeIterator iter = new ByteCodeIterator(codes); + ClassFile classFile = new ClassFile(); + + String magicNumber = iter.nextU4ToHexString(); + if (!"cafebabe".equalsIgnoreCase(magicNumber)) { + return null; + } + + classFile.setMinorVersion(iter.nextU2ToInt()); + classFile.setMajorVersion(iter.nextU2ToInt()); + + ConstantPool pool = parseConstantPool(iter); + classFile.setConstPool(pool); + + classFile.setAccessFlag(parseAccessFlag(iter)); + classFile.setClassIndex(parseClassIndex(iter)); + + // 目前没有处理接口 + parseInterfaces(iter); + + List fieldList = parseFields(iter, pool); + addFields(classFile, fieldList); + + List methodList = parseMethods(iter, classFile); + addMethods(classFile, methodList); + + return classFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + int flag = iter.nextU2ToInt(); + AccessFlag accessFlag = new AccessFlag(flag); + return accessFlag; + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + ClassIndex classIndex = new ClassIndex(); + int thisClassIndex = iter.nextU2ToInt(); + int superClassIndex = iter.nextU2ToInt(); + classIndex.setThisClassIndex(thisClassIndex); + classIndex.setSuperClassIndex(superClassIndex); + return classIndex; + + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + int size = iter.nextU2ToInt(); + System.out.println("ConstantPool size: " + size); + + ConstantPool pool = new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); // 添加无效的第0项 + + for (int i = 1; i < size; i++) { + int tag = iter.nextU1ToInt(); + + if (tag == ConstantInfo.UTF8_INFO) { + UTF8Info utf8Info = new UTF8Info(pool); + int length = iter.nextU2ToInt(); + String value = iter.nextLengthToString(length); + utf8Info.setLength(length); + utf8Info.setValue(value); + + pool.addConstantInfo(utf8Info); + } else if (tag == ConstantInfo.CLASS_INFO) { + ClassInfo classInfo = new ClassInfo(pool); + int index = iter.nextU2ToInt(); + classInfo.setUtf8Index(index); + + pool.addConstantInfo(classInfo); + } else if (tag == ConstantInfo.STRING_INFO) { + StringInfo stringInfo = new StringInfo(pool); + int index = iter.nextU2ToInt(); + stringInfo.setIndex(index); + + pool.addConstantInfo(stringInfo); + } else if (tag == ConstantInfo.FIELD_INFO) { + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + int classInfoIndex = iter.nextU2ToInt(); + int nameAndTypeIndex = iter.nextU2ToInt(); + fieldRefInfo.setClassInfoIndex(classInfoIndex); + fieldRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + + pool.addConstantInfo(fieldRefInfo); + } else if (tag == ClassInfo.METHOD_INFO) { + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + int classInfoIndex = iter.nextU2ToInt(); + int nameAndTypeIndex = iter.nextU2ToInt(); + methodRefInfo.setClassInfoIndex(classInfoIndex); + methodRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + + pool.addConstantInfo(methodRefInfo); + } else if (tag == ClassInfo.NAME_AND_TYPE_INFO) { + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + int index1 = iter.nextU2ToInt(); + int index2 = iter.nextU2ToInt(); + nameAndTypeInfo.setIndex1(index1); + nameAndTypeInfo.setIndex2(index2); + + pool.addConstantInfo(nameAndTypeInfo); + } else { + throw new RuntimeException("这个类型的常量还没有实现"); + } + + } + + return pool; + } + + private void parseInterfaces(ByteCodeIterator iter) { + int interfaceNum = iter.nextU2ToInt(); + if (interfaceNum != 0) { + throw new RuntimeException("有接口没有读取"); + } + } + + private List parseFields(ByteCodeIterator iter, ConstantPool pool) { + int filedNum = iter.nextU2ToInt(); + System.out.println("Field num: " + filedNum); + + List fieldList = new ArrayList<>(); + for (int i = 0; i < filedNum; i++) { + int accessFlag = iter.nextU2ToInt(); + int nameIndex = iter.nextU2ToInt(); + int descriptionIndex = iter.nextU2ToInt(); + int attributesCount = iter.nextU2ToInt(); + if (attributesCount != 0) { + throw new RuntimeException("字段的属性表没有处理"); + } + + fieldList.add(new Field(accessFlag, nameIndex, descriptionIndex, pool)); + } + + return fieldList; + } + + private void addFields(ClassFile classFile, List fieldList) { + for (Field field : fieldList) { + classFile.addField(field); + } + } + + private List parseMethods(ByteCodeIterator iter, ClassFile classFile) { + int methodNum = iter.nextU2ToInt(); + System.out.println("Methods num: " + methodNum); + + List methodList = new ArrayList<>(); + for (int i = 0; i < methodNum; i++) { + int accessFlag = iter.nextU2ToInt(); + int nameIndex = iter.nextU2ToInt(); + int descriptionIndex = iter.nextU2ToInt(); + + Method method = new Method(classFile, accessFlag, nameIndex, descriptionIndex); + + int attributesCount = iter.nextU2ToInt(); + for (int j = 0; j < attributesCount; j++) { + parseAttribute(iter, method, classFile); + } + + methodList.add(method); + } + return methodList; + } + + private void parseAttribute(ByteCodeIterator iter, Method method, ClassFile classFile) { + int nameIndex = iter.nextU2ToInt(); + int length = iter.nextU4ToInt(); + + if (AttributeInfo.CODE.equals(getUTF8ValueOfConstantPool(nameIndex, classFile))) { + CodeAttr codeAttr = parseCodeAttribute(iter, classFile); + method.setCodeAttr(codeAttr); + } else { + //TODO 目前没有处理除CODE外的其余属性 + iter.nextUxToHexString(length); + } + + } + + private CodeAttr parseCodeAttribute(ByteCodeIterator iter, ClassFile classFile) { + iter.back(6); // 因为之前验证类型时前进了6个字节,在此回退 + + int nameIndex = iter.nextU2ToInt(); + int length = iter.nextU4ToInt(); + int maxStack = iter.nextU2ToInt(); + int maxLocals = iter.nextU2ToInt(); + int codeLength = iter.nextU4ToInt(); + String code = iter.nextUxToHexString(codeLength); + + CodeAttr codeAttr = new CodeAttr(nameIndex, length, maxStack, maxLocals, codeLength, code); + + // TODO Code属性中的exception + int exceptionLength = iter.nextU2ToInt(); + if (exceptionLength != 0) { + throw new RuntimeException("Code属性中有异常字段没有处理"); + } + + // Code属性中的属性 + int attributesCount = iter.nextU2ToInt(); + for (int i = 0; i < attributesCount; i++) { + int attrNameIndex = iter.nextU2ToInt(); + int attrLength = iter.nextU4ToInt(); + + if (AttributeInfo.LINE_NUM_TABLE.equals(getUTF8ValueOfConstantPool(attrNameIndex, classFile))) { + LineNumberTable lineNumberTable = new LineNumberTable(attrNameIndex, attrLength); + codeAttr.setLineNumberTable(lineNumberTable); + iter.nextUxToHexString(attrLength); + } else if (AttributeInfo.LOCAL_VAR_TABLE.equals(getUTF8ValueOfConstantPool(attrNameIndex, classFile))) { + LocalVariableTable localVariableTable = new LocalVariableTable(attrNameIndex, attrLength); + codeAttr.setLocalVariableTable(localVariableTable); + iter.nextUxToHexString(attrLength); + } else { + String msg = "此属性:" + getUTF8ValueOfConstantPool(attrNameIndex, classFile) + "还没有处理"; + throw new RuntimeException(msg); + } + } + + return codeAttr; + } + + private void addMethods(ClassFile classFile, List methodList) { + for (Method method : methodList) { + classFile.addMethod(method); + } + } + + private String getUTF8ValueOfConstantPool(int index, ClassFile classFile) { + ConstantPool constantPool = classFile.getConstantPool(); + return constantPool.getUTF8String(index); + } + +} diff --git a/group01/765324639/src/main/java/minijvm/method/Method.java b/group01/765324639/src/main/java/minijvm/method/Method.java new file mode 100644 index 0000000000..3d0b9a5678 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/method/Method.java @@ -0,0 +1,54 @@ +package minijvm.method; + +import minijvm.attr.CodeAttr; +import minijvm.clz.ClassFile; +import minijvm.loader.ByteCodeIterator; + + + +public class Method { + + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + + private ClassFile clzFile; + + + public ClassFile getClzFile() { + return clzFile; + } + + public int getNameIndex() { + return nameIndex; + } + public int getDescriptorIndex() { + return descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr code) { + this.codeAttr = code; + } + + public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) { + this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + + + + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ + return null; + + } +} diff --git a/group01/765324639/src/main/java/minijvm/util/Util.java b/group01/765324639/src/main/java/minijvm/util/Util.java new file mode 100644 index 0000000000..e6370a4997 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/util/Util.java @@ -0,0 +1,24 @@ +package minijvm.util; + +public class Util { + public static int byteToInt(byte[] codes){ + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i tokenList = tokenParser.parse(); + Assert.assertEquals("2", tokenList.get(0).getValue()); + Assert.assertEquals("*", tokenList.get(3).getValue()); + Assert.assertEquals("5", tokenList.get(6).getValue()); + } + { + TokenParser tokenParser = new TokenParser("3*20+12*5-40/2"); + List tokenList = tokenParser.parse(); + Assert.assertEquals("20", tokenList.get(2).getValue()); + Assert.assertEquals("12", tokenList.get(4).getValue()); + Assert.assertEquals("5", tokenList.get(6).getValue()); + } + + } +} diff --git a/group01/765324639/src/test/java/download/FileDownloaderTest.java b/group01/765324639/src/test/java/download/FileDownloaderTest.java new file mode 100644 index 0000000000..e9ea374cb2 --- /dev/null +++ b/group01/765324639/src/test/java/download/FileDownloaderTest.java @@ -0,0 +1,61 @@ +package download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import download.api.ConnectionManager; +import download.api.DownloadListener; +import 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://121.42.185.101/forum/test.jpg"; // 此图片较大 + String url = "http://121.42.185.101/forum/weixin.jpg"; // 此图片较小 + + FileDownloader downloader = new FileDownloader(url); + + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + new Thread() { + @Override + public void run() { + downloader.execute(); + } + }.start(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("Downloaded not complete, sleep 5 second"); + // 休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("download complete!"); + + } + +} diff --git a/group01/765324639/src/test/java/litestruts/StrutsTest.java b/group01/765324639/src/test/java/litestruts/StrutsTest.java new file mode 100644 index 0000000000..45616a42cd --- /dev/null +++ b/group01/765324639/src/test/java/litestruts/StrutsTest.java @@ -0,0 +1,42 @@ +package 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/765324639/src/test/java/minijvm/loader/ClassFileloaderTest.java b/group01/765324639/src/test/java/minijvm/loader/ClassFileloaderTest.java new file mode 100644 index 0000000000..80586f51e2 --- /dev/null +++ b/group01/765324639/src/test/java/minijvm/loader/ClassFileloaderTest.java @@ -0,0 +1,274 @@ +package minijvm.loader; + +import java.io.File; +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import minijvm.clz.ClassFile; +import minijvm.clz.ClassIndex; +import minijvm.constant.ClassInfo; +import minijvm.constant.ConstantPool; +import minijvm.constant.MethodRefInfo; +import minijvm.constant.NameAndTypeInfo; +import minijvm.constant.UTF8Info; +import minijvm.field.Field; +import minijvm.method.Method; + + + +public class ClassFileloaderTest { + + private static final String FULL_QUALIFIED_CLASS_NAME = "minijvm/loader/EmployeeV1"; + + static String path1 = new File(".", "target\\test-classes").getAbsolutePath(); + static String path2 = "C:\\temp"; + + static String className = EmployeeV1.class.getName(); + + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "minijvm.loader.EmployeeV1"; + + try { + clzFile = loader.loadClass(className); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + clzFile.print(); + } + + @Before + public void setUp() throws Exception {} + + @After + public void tearDown() throws Exception {} + + @Test + public void testClassPath() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1 + ";" + path2, clzPath); + + } + + @Test + public void testClassFileLength() throws ClassNotFoundException { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1038, byteCodes.length); + + } + + @Test(expected = ClassNotFoundException.class) + public void testClassNotFindException() throws ClassNotFoundException { + ClassFileLoader loader = new ClassFileLoader(); + loader.readBinaryCode(className); + } + + + @Test + public void testMagicNumber() throws ClassNotFoundException { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[] {byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + + private String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + + @Test + public void testVersion(){ + + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool(){ + + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + /** + * 下面是第三次JVM课应实现的测试用例 + */ + @Test + public void testReadFields(){ + + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + @Test + public void testMethods(){ + + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } + +} diff --git a/group01/765324639/src/test/java/minijvm/loader/EmployeeV1.java b/group01/765324639/src/test/java/minijvm/loader/EmployeeV1.java new file mode 100644 index 0000000000..e501762cc4 --- /dev/null +++ b/group01/765324639/src/test/java/minijvm/loader/EmployeeV1.java @@ -0,0 +1,30 @@ +package minijvm.loader; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} diff --git a/group01/765324639/src/zavier/week01/basic/ArrayList.java b/group01/765324639/src/zavier/week01/basic/ArrayList.java deleted file mode 100644 index 38e5739fb8..0000000000 --- a/group01/765324639/src/zavier/week01/basic/ArrayList.java +++ /dev/null @@ -1,85 +0,0 @@ -package zavier.week01.basic; - -import java.util.Arrays; - -public class ArrayList implements List { - - private int size = 0; - - private Object[] elementData = new Object[100]; - - @Override - public void add(Object o) { - ensureCapacity(size + 1); - elementData[size++] = o; - } - - private void ensureCapacity(int size) { - if (size > elementData.length) { - grow(); - } - } - - private void grow() { - elementData = Arrays.copyOf(elementData, size * 2); - } - - @Override - public void add(int index, Object o) { - rangeCheckForAdd(index); - ensureCapacity(size + 1); - System.arraycopy(elementData, index, elementData, index + 1, size - index); - elementData[index] = o; - size++; - } - - private void rangeCheckForAdd(int index) { - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException(); - } - } - - @Override - public Object get(int index) { - rangeCheck(index); - return elementData[index]; - } - - private void rangeCheck(int index) { - if (index >= size || index < 0) { - throw new IndexOutOfBoundsException(); - } - } - - @Override - public Object remove(int index) { - rangeCheck(index); - Object dest = elementData[index]; - System.arraycopy(elementData, index + 1, elementData, index, size - index - 1); - size--; - return dest; - } - - @Override - public int size() { - return size; - } - - public Iterator iterator() { - return new Iterator() { - - private int index = 0; - - @Override - public Object next() { - return elementData[index++]; - } - - @Override - public boolean hasNext() { - return index < size; - } - }; - } - -} diff --git a/group01/765324639/src/zavier/week01/basic/BinaryTreeNode.java b/group01/765324639/src/zavier/week01/basic/BinaryTreeNode.java deleted file mode 100644 index 6ef26e8f9a..0000000000 --- a/group01/765324639/src/zavier/week01/basic/BinaryTreeNode.java +++ /dev/null @@ -1,63 +0,0 @@ -package zavier.week01.basic; - -public class BinaryTreeNode { - - private Integer data; - private BinaryTreeNode left; - private BinaryTreeNode right; - - public BinaryTreeNode(Integer data) { - this.data = data; - } - - public Integer getData() { - return data; - } - - public void setData(Integer 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(Integer o) { - - if (o > this.data) { - - if (this.getRight() == null) { - BinaryTreeNode node = new BinaryTreeNode(o); - this.setRight(node); - return node; - } else { - return this.getRight().insert(o); - } - - } else { - - if (this.getLeft() == null) { - BinaryTreeNode node = new BinaryTreeNode(o); - this.setLeft(node); - return node; - } else { - return this.getLeft().insert(o); - } - - } - - } - -} diff --git a/group01/765324639/src/zavier/week01/basic/Iterator.java b/group01/765324639/src/zavier/week01/basic/Iterator.java deleted file mode 100644 index 664983e0fd..0000000000 --- a/group01/765324639/src/zavier/week01/basic/Iterator.java +++ /dev/null @@ -1,8 +0,0 @@ -package zavier.week01.basic; - -public interface Iterator { - public boolean hasNext(); - - public Object next(); - -} diff --git a/group01/765324639/src/zavier/week01/basic/LinkedList.java b/group01/765324639/src/zavier/week01/basic/LinkedList.java deleted file mode 100644 index 6e15220b34..0000000000 --- a/group01/765324639/src/zavier/week01/basic/LinkedList.java +++ /dev/null @@ -1,375 +0,0 @@ -package zavier.week01.basic; - -import java.util.NoSuchElementException; - -public class LinkedList implements List { - - private Node head; - - private int size = 0; - - @Override - public void add(Object o) { - if (head == null) { - head = new Node(o); - } else { - Node tail = head; - while (tail.next != null) { - tail = tail.next; - } - Node node = new Node(o); - - tail.next = node; - } - size++; - } - - @Override - public void add(int index, Object o) { - rangeCheckForAdd(index); - if (index == 0) { - Node node = new Node(o); - node.next = head; - head = node; - } else { - Node preDest = head; - for (int i = 0; i < index - 1; i++) { - preDest = preDest.next; - } - Node node = new Node(o); - node.next = preDest.next; - preDest.next = node; - } - - size++; - } - - private void rangeCheckForAdd(int index) { - if (index > size || index < 0) { - throw new IndexOutOfBoundsException(); - } - } - - @Override - public Object get(int index) { - rangeCheck(index); - - Node dest = head; - for (int i = 0; i < index; i++) { - dest = dest.next; - } - return dest.data; - } - - private void rangeCheck(int index) { - if (index >= size || index < 0) { - throw new IndexOutOfBoundsException(); - } - } - - @Override - public Object remove(int index) { - rangeCheck(index); - - Node preDest = head; - for (int i = 0; i < index - 1; i++) { - preDest = preDest.next; - } - Node dest = preDest.next; - preDest.next = dest.next; - - size--; - return dest.data; - } - - @Override - public int size() { - return size; - } - - public void addFirst(Object o) { - Node node = new Node(o); - node.next = head; - head = node; - size++; - } - - public void addLast(Object o) { - Node lastNode = head; - while (lastNode.next != null) { - lastNode = lastNode.next; - } - - Node node = new Node(o); - lastNode.next = node; - size++; - } - - public Object removeFirst() { - if (head == null) { - throw new NoSuchElementException(); - } - Node target = head; - head = head.next; - size--; - return target.data; - } - - public Object removeLast() { - if (head == null) { - throw new NoSuchElementException(); - } - - Node preDest = head; - while (preDest.next.next != null) { - preDest = preDest.next; - } - Node dest = preDest.next; - preDest.next = null; - - size--; - return dest.data; - } - - public Iterator iterator() { - return null; - } - - - private static class Node { - Object data; - Node next; - - Node(Object data) { - this.data = data; - next = null; - } - } - - // =========================第三周作业========================= - - /** - * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 - */ - public void reverse() { - Node reverseNode = null; - while (head != null) { - Node temp = head; - head = head.next; - temp.next = reverseNode; - reverseNode = temp; - } - head = reverseNode; - } - - /** - * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 - */ - public void removeFirstHalf() { - int newStartIndex = size / 2; - for (int i = 0; i < newStartIndex; i++) { - head = head.next; - } - size = size - newStartIndex; - } - - /** - * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 - * - * @param i - * @param length - */ - public void remove(int i, int length) { - if (i < 0) { - throw new IllegalArgumentException(); - } - if (i + length >= size) { - length = size - i; - } - - if (i == 0) { - for (int j = 0; j < length; j++) { - head = head.next; - } - } else { - Node beforeRemoveStartNode = head; - for (int j = 0; j < i - 1; j++) { - beforeRemoveStartNode = beforeRemoveStartNode.next; - } - - Node removeEndNode = beforeRemoveStartNode; - for (int j = 0; j < length; j++) { - removeEndNode = removeEndNode.next; - } - - beforeRemoveStartNode.next = removeEndNode.next; - } - - size = size - length; - } - - /** - * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 例如当前链表 = 11->101->201->301->401->501->601->701 - * listB = 1->3->4->6 返回的结果应该是[101,301,401,601] - * - * @param list - */ - public int[] getElements(LinkedList list) { - checkList(list); - - int[] dest = new int[list.size]; - int arrayNum = 0; - Node temp = head; - int n = (int) list.get(0); - for (int i = 0; i < n; i++) { - temp = temp.next; - } - dest[arrayNum++] = (int) temp.data; - - for (int i = 1; i < list.size; i++) { - int num = (int) list.get(i) - (int) list.get(i - 1); - for (int j = 0; j < num; j++) { - temp = temp.next; - } - dest[arrayNum++] = (int) temp.data; - } - return dest; - } - - private void checkList(LinkedList list) { - for (int i = 0; i < list.size; i++) { - if ((int) list.get(i) < 0 || (int) list.get(i) >= size) { - throw new IllegalArgumentException("list中的元素位置越界"); - } - } - } - - /** - * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 - * - * @param list - */ - - public void subtract(LinkedList list) { - if (list == null || list.size == 0 || this.size == 0) { - return; - } - - int thisIndex = 0; - int listIndex = 0; - Node temp = head; - while (true) { // 后续需要优化替换remove()方法 - if ((int) temp.data < (int) list.get(listIndex)) { - temp = temp.next; - thisIndex++; - } else if ((int) temp.data == (int) list.get(listIndex)) { - this.remove(thisIndex); - temp = temp.next; - thisIndex++; - listIndex++; - } else { - listIndex++; - } - - if (thisIndex >= this.size || listIndex >= list.size) { - break; - } - } - } - - /** - * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) - */ - public void removeDuplicateValues() { - if (this.size == 0) { - return; - } - - Node subHead = head; - Node subTail = head; - - while (true) { - if (subTail == null) { - subHead.next = null; // 清除尾部重复的元素 - break; - } - if ((int) subTail.data == (int) subHead.data) { - if (!(subTail == subHead)) { // 判断两个指针是否指向同一个地方 - this.size--; - } - subTail = subTail.next; - } else { - subHead.next = subTail; - subHead = subHead.next; - } - } - } - - /** - * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) - * - * @param min - * @param max - */ - public void removeRange(int min, int max) { - if (this.size == 0) { - return; - } - - if ((int) head.data > max) { - throw new IllegalArgumentException(); - } - - int length = 0; - Node subList = new Node(null); - Node temp = subList; - while (true) { - if (head == null) { - break; - } - if ((int) head.data <= min || (int) head.data >= max) { - temp.next = head; - temp = temp.next; - length++; - } - head = head.next; - } - temp.next = null; // 去掉尾部多余数据 - head = subList.next; - size = length; - } - - /** - * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 - * - * @param list - */ - public LinkedList intersection(LinkedList list) { - if (this.size == 0 || list.size == 0) { - return null; - } - - Node tempHead = head; - int listIndex = 0; - - LinkedList newList = new LinkedList(); - while (true) { - if (tempHead == null || listIndex >= list.size) { - break; - } - - if ((int) tempHead.data < (int) list.get(listIndex)) { - tempHead = tempHead.next; - } else if ((int) tempHead.data > (int) list.get(listIndex)) { - listIndex++; - } else { - newList.add(tempHead.data); - - tempHead = tempHead.next; - listIndex++; - } - } - - return newList; - } -} diff --git a/group01/765324639/src/zavier/week01/basic/List.java b/group01/765324639/src/zavier/week01/basic/List.java deleted file mode 100644 index 4f2d49bd73..0000000000 --- a/group01/765324639/src/zavier/week01/basic/List.java +++ /dev/null @@ -1,13 +0,0 @@ -package zavier.week01.basic; - -public interface List { - public void add(Object o); - - public void add(int index, Object o); - - public Object get(int index); - - public Object remove(int index); - - public int size(); -} diff --git a/group01/765324639/src/zavier/week01/basic/Queue.java b/group01/765324639/src/zavier/week01/basic/Queue.java deleted file mode 100644 index 5a212d46c1..0000000000 --- a/group01/765324639/src/zavier/week01/basic/Queue.java +++ /dev/null @@ -1,25 +0,0 @@ -package zavier.week01.basic; - -public class Queue { - - private LinkedList list = new LinkedList(); - - public void enQueue(Object o) { - list.add(o); - } - - public Object deQueue() { - if (list.size() == 0) { - return null; - } - return list.removeFirst(); - } - - public boolean isEmpty() { - return list.size() == 0; - } - - public int size() { - return list.size(); - } -} diff --git a/group01/765324639/src/zavier/week01/basic/Stack.java b/group01/765324639/src/zavier/week01/basic/Stack.java deleted file mode 100644 index ebe4afb19f..0000000000 --- a/group01/765324639/src/zavier/week01/basic/Stack.java +++ /dev/null @@ -1,33 +0,0 @@ -package zavier.week01.basic; - -import java.util.EmptyStackException; - -public class Stack { - private ArrayList elementData = new ArrayList(); - - public void push(Object o) { - elementData.add(o); - } - - public Object pop() { - if (elementData.size() == 0) { - throw new EmptyStackException(); - } - return elementData.remove(elementData.size() - 1); - } - - public Object peek() { - if (elementData.size() == 0) { - throw new EmptyStackException(); - } - return elementData.get(elementData.size() - 1); - } - - public boolean isEmpty() { - return elementData.size() == 0; - } - - public int size() { - return elementData.size(); - } -} diff --git a/group01/765324639/src/zavier/week01/test/AllTests.java b/group01/765324639/src/zavier/week01/test/AllTests.java deleted file mode 100644 index c1755f6803..0000000000 --- a/group01/765324639/src/zavier/week01/test/AllTests.java +++ /dev/null @@ -1,12 +0,0 @@ -package zavier.week01.test; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ArrayListTest.class, LinkedListTest.class, QueueTest.class, StackTest.class, - BinaryTreeNodeTest.class}) -public class AllTests { - -} diff --git a/group01/765324639/src/zavier/week01/test/ArrayListTest.java b/group01/765324639/src/zavier/week01/test/ArrayListTest.java deleted file mode 100644 index 6a475500df..0000000000 --- a/group01/765324639/src/zavier/week01/test/ArrayListTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package zavier.week01.test; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import zavier.week01.basic.ArrayList; -import zavier.week01.basic.Iterator; - -public class ArrayListTest { - - private ArrayList arrayList = new ArrayList(); - - @Before - public void setUp() { - for (int i = 0; i < 500; i++) { - arrayList.add(i); - } - } - - @Test - public void testAddObject() { - for (int i = 0; i < 500; i++) { - arrayList.add(i); - } - } - - @Test - public void testAddIntObject() { - arrayList.add(100, -100); - Assert.assertEquals(-100, arrayList.get(100)); - Assert.assertEquals(100, arrayList.get(101)); - Assert.assertEquals(501, arrayList.size()); - } - - @Test(expected = IndexOutOfBoundsException.class) - public void testAddIllegalIntObject() { - arrayList.add(1000, 5); - } - - @Test(expected = IndexOutOfBoundsException.class) - public void testAddNegativeIntObject() { - arrayList.add(-1, 5); - } - - @Test - public void testGet() { - for (int i = 0; i < 500; i++) { - Assert.assertEquals(i, ((Integer) arrayList.get(i)).intValue()); - } - } - - @Test(expected = IndexOutOfBoundsException.class) - public void testIllegalGet() { - arrayList.get(500); - } - - @Test(expected = IndexOutOfBoundsException.class) - public void testNegativeGet() { - arrayList.get(-10); - } - - @Test - public void testRemove() { - Assert.assertEquals(100, arrayList.remove(100)); - Assert.assertEquals(101, arrayList.get(100)); - Assert.assertEquals(499, arrayList.size()); - } - - @Test(expected = IndexOutOfBoundsException.class) - public void testIllegalRemove() { - arrayList.remove(500); - } - - @Test - public void testSize() { - Assert.assertEquals(500, arrayList.size()); - } - - @Test - public void testIterator() { - Iterator iterator = arrayList.iterator(); - int i = 0; - while (iterator.hasNext()) { - Assert.assertEquals(i, iterator.next()); - i++; - } - Assert.assertEquals(500, i); - } - -} diff --git a/group01/765324639/src/zavier/week01/test/BinaryTreeNodeTest.java b/group01/765324639/src/zavier/week01/test/BinaryTreeNodeTest.java deleted file mode 100644 index 30a096a350..0000000000 --- a/group01/765324639/src/zavier/week01/test/BinaryTreeNodeTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package zavier.week01.test; - -import org.junit.Assert; -import org.junit.Test; - -import zavier.week01.basic.BinaryTreeNode; - -public class BinaryTreeNodeTest { - - private BinaryTreeNode root = new BinaryTreeNode(5); - - @Test - public void testInsert() { - root.insert(2); - root.insert(7); - root.insert(1); - root.insert(6); - - Assert.assertEquals((Integer) 5, root.getData()); - Assert.assertEquals((Integer) 2, root.getLeft().getData()); - Assert.assertEquals((Integer) 1, root.getLeft().getLeft().getData()); - Assert.assertEquals(null, root.getLeft().getRight()); - Assert.assertEquals((Integer) 7, root.getRight().getData()); - Assert.assertEquals((Integer) 6, root.getRight().getLeft().getData()); - Assert.assertEquals(null, root.getRight().getRight()); - - root.insert(4); - root.insert(8); - Assert.assertEquals((Integer) 4, root.getLeft().getRight().getData()); - Assert.assertEquals((Integer) 8, root.getRight().getRight().getData()); - } - -} diff --git a/group01/765324639/src/zavier/week01/test/LinkedListTest.java b/group01/765324639/src/zavier/week01/test/LinkedListTest.java deleted file mode 100644 index ea1f077704..0000000000 --- a/group01/765324639/src/zavier/week01/test/LinkedListTest.java +++ /dev/null @@ -1,259 +0,0 @@ -package zavier.week01.test; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import zavier.week01.basic.LinkedList; - - -public class LinkedListTest { - - private LinkedList linkedList = new LinkedList(); - - @Before - public void setUp() { - for (int i = 0; i < 500; i++) { - linkedList.add(i); - } - } - - @Test - public void testAddObject() { - for (int i = 0; i < 100; i++) { - linkedList.add(i); - } - Assert.assertEquals(600, linkedList.size()); - } - - @Test - public void testAddIntObject() { - linkedList.add(100, -100); - Assert.assertEquals(-100, linkedList.get(100)); - Assert.assertEquals(100, linkedList.get(101)); - } - - @Test(expected = IndexOutOfBoundsException.class) - public void testAddIllegalIntObject() { - linkedList.add(1000, 10); - } - - @Test(expected = IndexOutOfBoundsException.class) - public void testAddNegativeIntObject() { - linkedList.add(-10, 10); - } - - @Test - public void testGet() { - for (int i = 0; i < 500; i++) { - Assert.assertEquals(i, ((Integer) linkedList.get(i)).intValue()); - } - } - - @Test(expected = IndexOutOfBoundsException.class) - public void testIllegalGet() { - linkedList.get(500); - } - - @Test(expected = IndexOutOfBoundsException.class) - public void testNegativeGet() { - linkedList.get(-10); - } - - @Test - public void testRemove() { - Assert.assertEquals(100, linkedList.remove(100)); - Assert.assertEquals(101, linkedList.get(100)); - Assert.assertEquals(499, linkedList.size()); - } - - @Test - public void testSize() { - Assert.assertEquals(500, linkedList.size()); - linkedList.add(10); - Assert.assertEquals(501, linkedList.size()); - } - - @Test - public void testAddFirst() { - linkedList.addFirst(-10); - Assert.assertEquals(-10, linkedList.get(0)); - linkedList.addFirst(-100); - Assert.assertEquals(-100, linkedList.get(0)); - Assert.assertEquals(-10, linkedList.get(1)); - } - - @Test - public void testAddLast() { - linkedList.addLast(-9); - Assert.assertEquals(-9, linkedList.get(linkedList.size() - 1)); - linkedList.addLast(-8); - Assert.assertEquals(-8, linkedList.get(linkedList.size() - 1)); - Assert.assertEquals(-9, linkedList.get(linkedList.size() - 2)); - } - - @Test - public void testRemoveFirst() { - Assert.assertEquals(0, linkedList.removeFirst()); - Assert.assertEquals(1, linkedList.removeFirst()); - Assert.assertEquals(498, linkedList.size()); - } - - @Test - public void testRemoveLast() { - Assert.assertEquals(499, linkedList.removeLast()); - Assert.assertEquals(498, linkedList.removeLast()); - Assert.assertEquals(498, linkedList.size()); - } - - // =========================第三周作业========================= - - @Test - public void testReverse() { - linkedList.reverse(); - for (int i = 0; i < linkedList.size(); i++) { - Assert.assertEquals(499 - i, linkedList.get(i)); - } - Assert.assertEquals(500, linkedList.size()); - } - - @Test - public void testRemoveFirstHalfOfEven() { - linkedList.removeFirstHalf(); - for (int i = 250; i < 500; i++) { - Assert.assertEquals(i, linkedList.get(i - 250)); - } - Assert.assertEquals(250, linkedList.size()); - } - - @Test - public void testRemoveFirstHalfOfOdd() { - linkedList.add(500); - linkedList.removeFirstHalf(); - for (int i = 250; i < 501; i++) { - Assert.assertEquals(i, linkedList.get(i - 250)); - } - Assert.assertEquals(251, linkedList.size()); - } - - @Test - public void testRemoveIntInt() { - linkedList.remove(10, 10); - Assert.assertEquals(0, linkedList.get(0)); - Assert.assertEquals(20, linkedList.get(10)); - Assert.assertEquals(490, linkedList.size()); - } - - @Test(expected = IllegalArgumentException.class) - public void testIllegalIRemoveIntInt() { - linkedList.remove(-10, 10); - } - - @Test - public void testIllegalLengthRemoveIntInt() { - linkedList.remove(0, 10); - Assert.assertEquals(490, linkedList.size()); - Assert.assertEquals(10, linkedList.get(0)); - - linkedList.remove(300, 500); - Assert.assertEquals(300, linkedList.size()); - for (int i = 0; i < 300; i++) { - Assert.assertEquals(i + 10, linkedList.get(i)); - } - } - - @Test(expected = IllegalArgumentException.class) - public void testGetElements() { - LinkedList list = new LinkedList(); - list.add(5); - list.add(10); - list.add(202); - list.add(305); - Assert.assertArrayEquals(new int[] {5, 10, 202, 305}, linkedList.getElements(list)); - - Assert.assertEquals(500, linkedList.size()); - - list.add(500); - linkedList.getElements(list); - } - - @Test - public void testSubtract() { - LinkedList list1 = new LinkedList(); - list1.add(1); - list1.add(5); - list1.add(8); - list1.add(10); - LinkedList list2 = new LinkedList(); - list2.add(2); - list2.add(5); - list2.add(7); - list2.add(11); - list1.subtract(list2); - - Assert.assertEquals(1, list1.get(0)); - Assert.assertEquals(8, list1.get(1)); - Assert.assertEquals(10, list1.get(2)); - Assert.assertEquals(3, list1.size()); - } - - @Test - public void testRemoveDuplicateValues() { - LinkedList list = new LinkedList(); - list.add(1); - list.add(2); - list.add(2); - list.add(2); - list.add(3); - list.add(4); - list.add(5); - list.add(6); - list.add(6); - list.add(7); - list.add(7); - list.add(7); - - list.removeDuplicateValues(); - for (int i = 0; i < 7; i++) { - Assert.assertEquals(i + 1, list.get(i)); - } - Assert.assertEquals(7, list.size()); - } - - @Test - public void testRemoveRange() { - linkedList.removeRange(100, 300); - Assert.assertEquals(301, linkedList.size()); - for (int i = 0; i < 100; i++) { - Assert.assertEquals(i, linkedList.get(i)); - } - for (int i = 300; i < 500; i++) { - Assert.assertEquals(i, linkedList.get(i - 199)); - } - } - - @Test - public void testIntersection() { - LinkedList list1 = new LinkedList(); - list1.add(1); - list1.add(2); - list1.add(5); - list1.add(7); - list1.add(9); - - LinkedList list2 = new LinkedList(); - list2.add(0); - list2.add(2); - list2.add(9); - list2.add(10); - list2.add(19); - - LinkedList intersection = list1.intersection(list2); - Assert.assertNotNull(intersection); - Assert.assertEquals(2, intersection.size()); - Assert.assertEquals(2, (int) intersection.get(0)); - Assert.assertEquals(9, (int) intersection.get(1)); - - - } -} diff --git a/group01/765324639/src/zavier/week01/test/QueueTest.java b/group01/765324639/src/zavier/week01/test/QueueTest.java deleted file mode 100644 index 99d6466c8a..0000000000 --- a/group01/765324639/src/zavier/week01/test/QueueTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package zavier.week01.test; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import zavier.week01.basic.Queue; - -public class QueueTest { - - private Queue queue = new Queue(); - - @Before - public void setUp() { - for (int i = 0; i < 500; i++) { - queue.enQueue(i); - } - } - - @Test - public void testEnQueue() { - for (int i = 0; i < 100; i++) { - queue.enQueue(i); - } - Assert.assertEquals(600, queue.size()); - } - - @Test - public void testDeQueue() { - for (int i = 0; i < 500; i++) { - Assert.assertEquals(i, queue.deQueue()); - } - Assert.assertNull(queue.deQueue()); - Assert.assertNull(queue.deQueue()); - } - - @Test - public void testIsEmpty() { - Assert.assertFalse(queue.isEmpty()); - Queue q = new Queue(); - Assert.assertTrue(q.isEmpty()); - } - - @Test - public void testSize() { - Assert.assertEquals(500, queue.size()); - } - -} diff --git a/group01/765324639/src/zavier/week01/test/StackTest.java b/group01/765324639/src/zavier/week01/test/StackTest.java deleted file mode 100644 index 8138f97d3d..0000000000 --- a/group01/765324639/src/zavier/week01/test/StackTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package zavier.week01.test; - -import java.util.EmptyStackException; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import zavier.week01.basic.Stack; - - -public class StackTest { - - private Stack stack = new Stack(); - - @Before - public void setUp() { - for (int i = 0; i < 500; i++) { - stack.push(i); - } - } - - @Test - public void testPush() { - for (int i = 0; i < 100; i++) { - stack.push(i); - } - Assert.assertEquals(600, stack.size()); - } - - @Test(expected = EmptyStackException.class) - public void testPop() { - for (int i = 0; i < 500; i++) { - Assert.assertEquals(499 - i, stack.pop()); - } - stack.pop(); - } - - @Test - public void testPeek() { - Assert.assertEquals(499, stack.peek()); - Assert.assertEquals(499, stack.peek()); - stack.pop(); - Assert.assertEquals(498, stack.peek()); - } - - @Test - public void testIsEmpty() { - Assert.assertFalse(stack.isEmpty()); - Assert.assertTrue(new Stack().isEmpty()); - } - - @Test - public void testSize() { - Assert.assertEquals(500, stack.size()); - stack.pop(); - Assert.assertEquals(499, stack.size()); - } - -} diff --git a/group01/765324639/src/zavier/week02/coderising/array/ArrayUtil.java b/group01/765324639/src/zavier/week02/coderising/array/ArrayUtil.java deleted file mode 100644 index 96bff301c7..0000000000 --- a/group01/765324639/src/zavier/week02/coderising/array/ArrayUtil.java +++ /dev/null @@ -1,263 +0,0 @@ -package zavier.week02.coderising.array; - -import zavier.week01.basic.ArrayList; -import zavier.week01.basic.List; - -public class ArrayUtil { - - /** - * 给定一个整形数组a , 对该数组的值进行置换 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] 如果 a = [7, 9, 30, 3, 4] , - * 置换后为 [4,3, 30 , 9,7] - * - * @param origin - * @return - */ - public void reverseArray(int[] origin) { - if (origin == null) { - throw new IllegalArgumentException(); - } - - int temp; - for (int i = 0; i < origin.length / 2; i++) { - temp = origin[i]; - origin[i] = origin[origin.length - 1 - i]; - origin[origin.length - 1 - i] = temp; - } - } - - /** - * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} - * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: {1,3,4,5,6,6,5,4,7,6,7,5} - * - * @param oldArray - * @return - */ - - public int[] removeZero(int[] oldArray) { - if (oldArray == null) { - throw new IllegalArgumentException(); - } - - int[] noZeroArray = new int[oldArray.length]; - int index = 0; - for (int i = 0; i < oldArray.length; i++) { - if (oldArray[i] != 0) { - noZeroArray[index++] = oldArray[i]; - } - } - - return copyOf(noZeroArray, index); - } - - /** - * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 例如 a1 = [3, 5, 7,8] a2 = [4, - * 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 - * - * @param array1 - * @param array2 - * @return - */ - - public int[] merge(int[] array1, int[] array2) { - if (array1 == null || array2 == null) { - throw new IllegalArgumentException(); - } - - int indexOfArray1 = 0; - int indexOfArray2 = 0; - int totalLength = array1.length + array2.length; - int[] destArr = new int[totalLength]; - - for (int i = 0; i < totalLength; i++) { - if (indexOfArray1 >= array1.length) { - // array1填充完毕,将array2填充剩下的元素 - arrayCopy(array2, indexOfArray2, destArr, i, array2.length - indexOfArray2); - int actualSize = i + array2.length - indexOfArray2; - return copyOf(destArr, actualSize); - } - - if (indexOfArray2 >= array2.length) { - arrayCopy(array1, indexOfArray1, destArr, i, array1.length - indexOfArray1); - int actualSize = i + array1.length - indexOfArray1; - return copyOf(destArr, actualSize); - } - - if (array1[indexOfArray1] < array2[indexOfArray2]) { - destArr[i] = array1[indexOfArray1]; - indexOfArray1++; - } else if (array1[indexOfArray1] == array2[indexOfArray2]) { - destArr[i] = array1[indexOfArray1]; - indexOfArray1++; - indexOfArray2++; // 去除重复元素 - } else { - destArr[i] = array2[indexOfArray2]; - indexOfArray2++; - } - - } - // array1.length、array2.length均为0的情况 - return new int[0]; - } - - private void arrayCopy(int[] src, int srcPos, int[] dest, int destPos, int length) { - for (int i = 0; i < length; i++) { - dest[destPos++] = src[srcPos++]; - } - } - - private int[] copyOf(int[] original, int newLength) { - int[] dest = new int[newLength]; - for (int i = 0; i < newLength; i++) { - dest[i] = original[i]; - } - return dest; - } - - /** - * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size 注意,老数组的元素在新数组中需要保持 例如 oldArray - * = [2,3,6] , size = 3,则返回的新数组为 [2,3,6,0,0,0] - * - * @param oldArray - * @param size - * @return - */ - public int[] grow(int[] oldArray, int size) { - if (oldArray == null || size < 0) { - throw new IllegalArgumentException(); - } - - int newSize = oldArray.length + size; - int[] newArray = new int[newSize]; - for (int i = 0; i < oldArray.length; i++) { - newArray[i] = oldArray[i]; - } - return newArray; - } - - /** - * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] - * max = 1, 则返回空数组 [] - * - * @param max - * @return - */ - public int[] fibonacci(int max) { - if (max < 0) { - throw new IllegalArgumentException(); - } - if (max == 1) { - return new int[] {}; - } - - ArrayList list = new ArrayList(); - list.add(1); - list.add(1); - - int i = 0; - while (true) { - int num = (int) list.get(i) + (int) list.get(i + 1); - if (num < max) { - list.add(num); - } else { - break; - } - i++; - } - - return intListToArray(list); - } - - private int[] intListToArray(List list) { - int[] array = new int[list.size()]; - for (int i = 0; i < list.size(); i++) { - array[i] = (int) list.get(i); - } - return array; - } - - /** - * 返回小于给定最大值max的所有素数数组 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] - * - * @param max - * @return - */ - public int[] getPrimes(int max) { - if (max < 0) { - throw new IllegalArgumentException(); - } - - ArrayList list = new ArrayList(); - for (int i = 2; i < max; i++) { - if (isPrime(i)) { - list.add(i); - } - } - return intListToArray(list); - } - - private boolean isPrime(int num) { - for (int i = 2; i <= num / 2; i++) { - if (num % i == 0) { - return false; - } - } - return true; - } - - /** - * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 - * - * @param max - * @return - */ - public int[] getPerfectNumbers(int max) { - if (max < 0) { - throw new IllegalArgumentException(); - } - - ArrayList list = new ArrayList(); - for (int i = 2; i < max; i++) { - if (isPerfectNumber(i)) { - list.add(i); - } - } - return intListToArray(list); - } - - private boolean isPerfectNumber(int num) { - int sumOfFactor = 1; - for (int i = 2; i <= num / 2; i++) { - if (num % i == 0) { - sumOfFactor += i; - } - } - if (sumOfFactor == 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) { - if (array == null) { - throw new IllegalArgumentException(); - } - if (array.length == 0) { - return ""; - } - - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < array.length; i++) { - builder.append(array[i]).append(seperator); - } - return builder.substring(0, builder.length() - seperator.length()); - } - - -} diff --git a/group01/765324639/src/zavier/week02/coderising/array/ArrayUtilTest.java b/group01/765324639/src/zavier/week02/coderising/array/ArrayUtilTest.java deleted file mode 100644 index d0e6fa11d8..0000000000 --- a/group01/765324639/src/zavier/week02/coderising/array/ArrayUtilTest.java +++ /dev/null @@ -1,133 +0,0 @@ -package zavier.week02.coderising.array; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class ArrayUtilTest { - - private ArrayUtil arrayUtil; - - @Before - public void setUp() { - arrayUtil = new ArrayUtil(); - } - - @Test - public void testReverseArray() { - int[] a = {}; - arrayUtil.reverseArray(a); - Assert.assertArrayEquals(new int[] {}, a); - - int[] b = {1, 2, 3}; - arrayUtil.reverseArray(b); - Assert.assertArrayEquals(new int[] {3, 2, 1}, b); - - int[] c = {1, 2, 3, 4}; - arrayUtil.reverseArray(c); - Assert.assertArrayEquals(new int[] {4, 3, 2, 1}, c); - - int[] d = new int[5000]; - int[] d1 = new int[5000]; - for (int i = 0; i < 5000; i++) { - d[i] = i; - d1[i] = 4999 - i; - } - arrayUtil.reverseArray(d); - Assert.assertArrayEquals(d1, d); - } - - @Test(expected = IllegalArgumentException.class) - public void testRemoveZero() { - int oldArr1[] = {1, 3, 4, 5, 0, 0, 6, 6, 0, 5, 4, 7, 6, 7, 0, 5}; - int newArr1[] = {1, 3, 4, 5, 6, 6, 5, 4, 7, 6, 7, 5}; - Assert.assertArrayEquals(newArr1, arrayUtil.removeZero(oldArr1)); - - int oldArr2[] = {0, 0, 0, 0, 0}; - int newArr2[] = {}; - Assert.assertArrayEquals(newArr2, arrayUtil.removeZero(oldArr2)); - - int oldArr3[] = {0, 0, 0, 0, 0, 1, 2, 3}; - int newArr3[] = {1, 2, 3}; - Assert.assertArrayEquals(newArr3, arrayUtil.removeZero(oldArr3)); - - int oldArr4[] = {1, 2, 3, 0, 0, 0, 0, 0}; - int newArr4[] = {1, 2, 3}; - Assert.assertArrayEquals(newArr4, arrayUtil.removeZero(oldArr4)); - - int oldArr5[] = {0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0}; - int newArr5[] = {1, 2, 3, 4}; - Assert.assertArrayEquals(newArr5, arrayUtil.removeZero(oldArr5)); - - int oldArr6[] = {}; - int newArr6[] = {}; - Assert.assertArrayEquals(newArr6, oldArr6); - - arrayUtil.removeZero(null); - } - - @Test - public void testMerge() { - int[] a1 = {3, 5, 7, 8}; - int[] a2 = {4, 5, 6, 7}; - Assert.assertArrayEquals(new int[] {3, 4, 5, 6, 7, 8}, arrayUtil.merge(a1, a2)); - - int[] b1 = {1, 2, 9, 100}; - int[] b2 = {3, 4, 5, 90, 100}; - Assert.assertArrayEquals(new int[] {1, 2, 3, 4, 5, 9, 90, 100}, arrayUtil.merge(b1, b2)); - - int[] c1 = {}; - int[] c2 = {1, 2, 3}; - Assert.assertArrayEquals(new int[] {1, 2, 3}, arrayUtil.merge(c1, c2)); - - int[] d1 = {}; - int[] d2 = {}; - Assert.assertArrayEquals(new int[] {}, arrayUtil.merge(d1, d2)); - } - - @Test - public void testGrow() { - int[] a1 = {2, 3, 6}; - Assert.assertArrayEquals(new int[] {2, 3, 6, 0, 0, 0}, arrayUtil.grow(a1, 3)); - Assert.assertArrayEquals(new int[] {2, 3, 6}, arrayUtil.grow(a1, 0)); - } - - @Test - public void testFibonacci() { - Assert.assertArrayEquals(new int[] {}, arrayUtil.fibonacci(1)); - Assert.assertArrayEquals(new int[] {1, 1, 2, 3, 5, 8, 13}, arrayUtil.fibonacci(15)); - - int[] a = new int[] {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, - 2584, 4181, 6765}; - Assert.assertArrayEquals(a, arrayUtil.fibonacci(6766)); - } - - @Test - public void testGetPrimes() { - Assert.assertArrayEquals(new int[] {}, arrayUtil.getPrimes(1)); - Assert.assertArrayEquals(new int[] {}, arrayUtil.getPrimes(2)); - Assert.assertArrayEquals(new int[] {2, 3, 5, 7, 11, 13, 17, 19}, arrayUtil.getPrimes(23)); - Assert.assertArrayEquals(new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, - 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, - 149, 151, 157, 163, 167, 173, 179}, arrayUtil.getPrimes(181)); - } - - @Test - public void testGetPerfectNumbers() { - Assert.assertArrayEquals(new int[] {6}, arrayUtil.getPerfectNumbers(7)); - Assert.assertArrayEquals(new int[] {6, 28}, arrayUtil.getPerfectNumbers(496)); - Assert.assertArrayEquals(new int[] {6, 28, 496}, arrayUtil.getPerfectNumbers(497)); - Assert.assertArrayEquals(new int[] {6, 28, 496, 8128}, arrayUtil.getPerfectNumbers(8129)); - - } - - @Test - public void testJoin() { - Assert.assertEquals("", arrayUtil.join(new int[] {}, "-")); - Assert.assertEquals("1", arrayUtil.join(new int[] {1}, "-")); - Assert.assertEquals("1-2-8-3-4-5", arrayUtil.join(new int[] {1, 2, 8, 3, 4, 5}, "-")); - Assert.assertEquals("1*-*2*-*8*-*3*-*4*-*5", - arrayUtil.join(new int[] {1, 2, 8, 3, 4, 5}, "*-*")); - } - -} diff --git a/group01/765324639/src/zavier/week02/coderising/litestruts/LoginAction.java b/group01/765324639/src/zavier/week02/coderising/litestruts/LoginAction.java deleted file mode 100644 index 617b5f115b..0000000000 --- a/group01/765324639/src/zavier/week02/coderising/litestruts/LoginAction.java +++ /dev/null @@ -1,42 +0,0 @@ -package zavier.week02.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/765324639/src/zavier/week02/coderising/litestruts/Struts.java b/group01/765324639/src/zavier/week02/coderising/litestruts/Struts.java deleted file mode 100644 index d30beaafb3..0000000000 --- a/group01/765324639/src/zavier/week02/coderising/litestruts/Struts.java +++ /dev/null @@ -1,117 +0,0 @@ -package zavier.week02.coderising.litestruts; - -import java.io.InputStream; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.Element; -import org.dom4j.io.SAXReader; - - - -public class Struts { - - public static 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 { - - SAXReader reader = new SAXReader(); - InputStream struts = Struts.class.getResourceAsStream("struts.xml"); - Document document = null; - try { - document = reader.read(struts); - } catch (DocumentException e) { - e.printStackTrace(); - } - - String className = ""; // actionName对应的类名 - Element rootElement = document.getRootElement(); - Iterator iterator = rootElement.elementIterator("action"); - Element targetAction = null; // actionName对应的action - while (iterator.hasNext()) { - Element element = (Element) iterator.next(); - String name = element.attributeValue("name"); - if (name.equals(actionName)) { - className = element.attributeValue("class"); - targetAction = element; - break; - } - } - - - Class class1 = Class.forName(className); - Object instance = class1.newInstance(); - - Set keySet = parameters.keySet(); - for (String key : keySet) { - // 将变量名拼成对应的set方法名 - String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); - Class type = class1.getDeclaredField(key).getType(); - Method method = class1.getDeclaredMethod(methodName, type); - // 依次调用对应的set方法 - method.invoke(instance, parameters.get(key)); - } - - String result = (String) class1.getDeclaredMethod("execute").invoke(instance); - - Method[] declaredMethods = class1.getDeclaredMethods(); - HashMap map = new HashMap<>(); - for (int i = 0; i < declaredMethods.length; i++) { - if (declaredMethods[i].getName().startsWith("get")) { - String fieldValue = (String) declaredMethods[i].invoke(instance); - String fieldName = methodNameToFieldName(declaredMethods[i].getName()); - map.put(fieldName, fieldValue); - } - } - - View view = new View(); - view.setParameters(map); - - Iterator elementIterator = targetAction.elementIterator("result"); - while (elementIterator.hasNext()) { - Element element = (Element) elementIterator.next(); - if (result.equals(element.attributeValue("name"))) { - view.setJsp(element.getText()); - } - } - - return view; - - - } catch (Exception e1) { - e1.printStackTrace(); - } - - return null; - } - - private static String methodNameToFieldName(String methodName) { - if (!methodName.startsWith("get") && !methodName.startsWith("set")) { - throw new IllegalArgumentException(); - } - - return methodName.substring(3, 4).toLowerCase() + methodName.substring(4); - } - -} diff --git a/group01/765324639/src/zavier/week02/coderising/litestruts/StrutsTest.java b/group01/765324639/src/zavier/week02/coderising/litestruts/StrutsTest.java deleted file mode 100644 index ba800c2fdc..0000000000 --- a/group01/765324639/src/zavier/week02/coderising/litestruts/StrutsTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package zavier.week02.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/765324639/src/zavier/week02/coderising/litestruts/View.java b/group01/765324639/src/zavier/week02/coderising/litestruts/View.java deleted file mode 100644 index f164c4bfc5..0000000000 --- a/group01/765324639/src/zavier/week02/coderising/litestruts/View.java +++ /dev/null @@ -1,26 +0,0 @@ -package zavier.week02.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/765324639/src/zavier/week02/coderising/litestruts/struts.xml b/group01/765324639/src/zavier/week02/coderising/litestruts/struts.xml deleted file mode 100644 index ffe9110788..0000000000 --- a/group01/765324639/src/zavier/week02/coderising/litestruts/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - \ No newline at end of file diff --git a/group01/765324639/src/zavier/week03/coderising/download/DownloadThread.java b/group01/765324639/src/zavier/week03/coderising/download/DownloadThread.java deleted file mode 100644 index f94c97b8b1..0000000000 --- a/group01/765324639/src/zavier/week03/coderising/download/DownloadThread.java +++ /dev/null @@ -1,44 +0,0 @@ -package zavier.week03.coderising.download; - -import java.io.IOException; -import java.io.RandomAccessFile; - -import zavier.week03.coderising.download.api.Connection; - -public class DownloadThread extends Thread { - - Connection conn; - int startPos; - int endPos; - - - public DownloadThread(Connection conn, int startPos, int endPos) { - - this.conn = conn; - this.startPos = startPos; - this.endPos = endPos; - - } - - @Override - public void run() { - byte[] data = new byte[endPos - startPos]; - try { - data = conn.read(startPos, endPos); - } catch (IOException e) { - e.printStackTrace(); - } - writeToFile(data); - } - - private void writeToFile(byte[] data) { - RandomAccessFile file; - try { - file = new RandomAccessFile("download20170311.jpg", "rw"); - file.seek(startPos); - file.write(data, 0, data.length); - } catch (IOException e) { - e.printStackTrace(); - } - } -} diff --git a/group01/765324639/src/zavier/week03/coderising/download/FileDownloader.java b/group01/765324639/src/zavier/week03/coderising/download/FileDownloader.java deleted file mode 100644 index ff2db12f50..0000000000 --- a/group01/765324639/src/zavier/week03/coderising/download/FileDownloader.java +++ /dev/null @@ -1,87 +0,0 @@ -package zavier.week03.coderising.download; - -import zavier.week03.coderising.download.api.Connection; -import zavier.week03.coderising.download.api.ConnectionException; -import zavier.week03.coderising.download.api.ConnectionManager; -import zavier.week03.coderising.download.api.DownloadListener; - - -public class FileDownloader { - - String url; - - DownloadListener listener; - - ConnectionManager cm; - - - public FileDownloader(String _url) { - this.url = _url; - - } - - public void execute() { - // 在这里实现你的代码, 注意: 需要用多线程实现下载 - // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 - // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) - // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 - // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 - // 具体的实现思路: - // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 - // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 - // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 - // 3. 把byte数组写入到文件中 - // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 - - // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 - Connection conn = null; - try { - - conn = cm.open(this.url); - - int length = conn.getContentLength(); - - DownloadThread downloadThread1 = new DownloadThread(conn, 0, length / 3); - downloadThread1.start(); - DownloadThread downloadThread2 = - new DownloadThread(conn, length / 3 + 1, length / 3 * 2); - downloadThread2.start(); - DownloadThread downloadThread3 = - new DownloadThread(conn, length / 3 * 2 + 1, length - 1); - downloadThread3.start(); - try { - downloadThread1.join(); - downloadThread2.join(); - downloadThread3.join(); - listener.notifyFinished(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - } catch (ConnectionException e) { - e.printStackTrace(); - } finally { - if (conn != null) { - conn.close(); - } - } - - - - } - - public void setListener(DownloadListener listener) { - this.listener = listener; - } - - - - public void setConnectionManager(ConnectionManager ucm) { - this.cm = ucm; - } - - public DownloadListener getListener() { - return this.listener; - } - -} diff --git a/group01/765324639/src/zavier/week03/coderising/download/FileDownloaderTest.java b/group01/765324639/src/zavier/week03/coderising/download/FileDownloaderTest.java deleted file mode 100644 index bf67e8d494..0000000000 --- a/group01/765324639/src/zavier/week03/coderising/download/FileDownloaderTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package zavier.week03.coderising.download; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import zavier.week03.coderising.download.api.ConnectionManager; -import zavier.week03.coderising.download.api.DownloadListener; -import zavier.week03.coderising.download.impl.ConnectionManagerImpl; - -public class FileDownloaderTest { - boolean downloadFinished = false; - - @Before - public void setUp() throws Exception {} - - @After - public void tearDown() throws Exception {} - - @Test - public void testDownload() { - - String url = "http://121.42.185.101/forum/test.jpg"; - - FileDownloader downloader = new FileDownloader(url); - - - ConnectionManager cm = new ConnectionManagerImpl(); - downloader.setConnectionManager(cm); - - downloader.setListener(new DownloadListener() { - @Override - public void notifyFinished() { - downloadFinished = true; - } - - }); - - new Thread() { - @Override - public void run() { - downloader.execute(); - } - }.start(); - - // 等待多线程下载程序执行完毕 - while (!downloadFinished) { - try { - System.out.println("还没有下载完成,休眠五秒"); - // 休眠5秒 - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - System.out.println("下载完成!"); - - - - } - -} diff --git a/group01/765324639/src/zavier/week03/coderising/download/api/Connection.java b/group01/765324639/src/zavier/week03/coderising/download/api/Connection.java deleted file mode 100644 index 4763202fab..0000000000 --- a/group01/765324639/src/zavier/week03/coderising/download/api/Connection.java +++ /dev/null @@ -1,26 +0,0 @@ -package zavier.week03.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/group01/765324639/src/zavier/week03/coderising/download/api/ConnectionException.java b/group01/765324639/src/zavier/week03/coderising/download/api/ConnectionException.java deleted file mode 100644 index 5df32804de..0000000000 --- a/group01/765324639/src/zavier/week03/coderising/download/api/ConnectionException.java +++ /dev/null @@ -1,5 +0,0 @@ -package zavier.week03.coderising.download.api; - -public class ConnectionException extends Exception { - -} diff --git a/group01/765324639/src/zavier/week03/coderising/download/api/ConnectionManager.java b/group01/765324639/src/zavier/week03/coderising/download/api/ConnectionManager.java deleted file mode 100644 index 81f5f34f72..0000000000 --- a/group01/765324639/src/zavier/week03/coderising/download/api/ConnectionManager.java +++ /dev/null @@ -1,11 +0,0 @@ -package zavier.week03.coderising.download.api; - -public interface ConnectionManager { - /** - * 给定一个url , 打开一个连接 - * - * @param url - * @return - */ - public Connection open(String url) throws ConnectionException; -} diff --git a/group01/765324639/src/zavier/week03/coderising/download/api/DownloadListener.java b/group01/765324639/src/zavier/week03/coderising/download/api/DownloadListener.java deleted file mode 100644 index f72ecd263d..0000000000 --- a/group01/765324639/src/zavier/week03/coderising/download/api/DownloadListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package zavier.week03.coderising.download.api; - -public interface DownloadListener { - public void notifyFinished(); -} diff --git a/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionImpl.java b/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionImpl.java deleted file mode 100644 index b297beef54..0000000000 --- a/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package zavier.week03.coderising.download.impl; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; - -import zavier.week03.coderising.download.api.Connection; - -public class ConnectionImpl implements Connection { - - private URL url = null;; - - private HttpURLConnection conn = null; - - public ConnectionImpl(String url) { - try { - this.url = new URL(url); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - } - - @Override - public byte[] read(int startPos, int endPos) throws IOException { - try { - conn = (HttpURLConnection) url.openConnection(); - } catch (IOException e) { - e.printStackTrace(); - } - conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); - InputStream inputStream = conn.getInputStream(); - byte[] result = new byte[endPos - startPos + 1]; - byte[] data = new byte[1024]; - int read = -1; - int i = 0; - while ((read = inputStream.read(data, 0, data.length)) != -1) { - System.arraycopy(data, 0, result, i, read); - i += read; - } - return result; - } - - @Override - public int getContentLength() { - HttpURLConnection openConnection = null; - try { - openConnection = (HttpURLConnection) url.openConnection(); - } catch (IOException e) { - e.printStackTrace(); - } - int contentLength = openConnection.getContentLength(); - openConnection.disconnect(); - return contentLength; - } - - @Override - public void close() { - conn.disconnect(); - conn = null; - } - -} diff --git a/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionManagerImpl.java b/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionManagerImpl.java deleted file mode 100644 index d6828e7ae8..0000000000 --- a/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionManagerImpl.java +++ /dev/null @@ -1,14 +0,0 @@ -package zavier.week03.coderising.download.impl; - -import zavier.week03.coderising.download.api.Connection; -import zavier.week03.coderising.download.api.ConnectionException; -import zavier.week03.coderising.download.api.ConnectionManager; - -public class ConnectionManagerImpl implements ConnectionManager { - - @Override - public Connection open(String url) throws ConnectionException { - return new ConnectionImpl(url); - } - -} diff --git a/group01/765324639/src/zavier/week04/coderising/jvm/loader/ClassFileLoader.java b/group01/765324639/src/zavier/week04/coderising/jvm/loader/ClassFileLoader.java deleted file mode 100644 index 92a3fcfe02..0000000000 --- a/group01/765324639/src/zavier/week04/coderising/jvm/loader/ClassFileLoader.java +++ /dev/null @@ -1,72 +0,0 @@ -package zavier.week04.coderising.jvm.loader; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - - - -public class ClassFileLoader { - - private List clzPaths = new ArrayList(); - - public byte[] readBinaryCode(String className) throws ClassNotFoundException { - File classFile = getClassFile(className); - return readFileToByteArray(classFile); - } - - private File getClassFile(String className) throws ClassNotFoundException { - File classFile = null; - String classFilePath = convertClassNameToFilePath(className); - for (String path : clzPaths) { - File file = new File(path, classFilePath); - if (file.exists()) { - classFile = file; - break; - } - } - - if (classFile == null) { // 文件不存在 - throw new ClassNotFoundException(); - } - return classFile; - } - - private byte[] readFileToByteArray(File classFile) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try (InputStream in = new FileInputStream(classFile);) { - byte[] data = new byte[1024]; - int len = -1; - while ((len = in.read(data)) != -1) { - out.write(data, 0, len); - } - } catch (FileNotFoundException e) { // 调用此函数时,已经确定文件是存在的 - e.printStackTrace(); - } catch (IOException e1) { - e1.printStackTrace(); - } - return out.toByteArray(); - } - - private String convertClassNameToFilePath(String fillClassName) { - return fillClassName.replace(".", "\\") + ".class"; - } - - public void addClassPath(String path) { - clzPaths.add(path); - } - - - - public String getClassPath() { - return String.join(";", clzPaths); - } - - - -} diff --git a/group01/765324639/src/zavier/week04/coderising/jvm/test/ClassFileloaderTest.java b/group01/765324639/src/zavier/week04/coderising/jvm/test/ClassFileloaderTest.java deleted file mode 100644 index 66855937f4..0000000000 --- a/group01/765324639/src/zavier/week04/coderising/jvm/test/ClassFileloaderTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package zavier.week04.coderising.jvm.test; - -import java.io.File; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import zavier.week04.coderising.jvm.loader.ClassFileLoader; - - - -public class ClassFileloaderTest { - - - static String path1 = new File(".", "bin").getAbsolutePath(); - static String path2 = "C:\\temp"; - - static String className = EmployeeV1.class.getName(); - - @Before - public void setUp() throws Exception {} - - @After - public void tearDown() throws Exception {} - - @Test - public void testClassPath() { - - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - loader.addClassPath(path2); - - String clzPath = loader.getClassPath(); - - Assert.assertEquals(path1 + ";" + path2, clzPath); - - } - - @Test - public void testClassFileLength() throws ClassNotFoundException { - - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - - byte[] byteCodes = loader.readBinaryCode(className); - - // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 - Assert.assertEquals(1076, byteCodes.length); - - } - - @Test(expected = ClassNotFoundException.class) - public void testClassNotFindException() throws ClassNotFoundException { - ClassFileLoader loader = new ClassFileLoader(); - loader.readBinaryCode(className); - } - - - @Test - public void testMagicNumber() throws ClassNotFoundException { - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - byte[] byteCodes = loader.readBinaryCode(className); - byte[] codes = new byte[] {byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3]}; - - - String acctualValue = this.byteToHexString(codes); - - Assert.assertEquals("cafebabe", acctualValue); - } - - - - private String byteToHexString(byte[] codes) { - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < codes.length; i++) { - byte b = codes[i]; - int value = b & 0xFF; - String strHex = Integer.toHexString(value); - if (strHex.length() < 2) { - strHex = "0" + strHex; - } - buffer.append(strHex); - } - return buffer.toString(); - } - -} diff --git a/group01/765324639/src/zavier/week04/coderising/jvm/test/EmployeeV1.java b/group01/765324639/src/zavier/week04/coderising/jvm/test/EmployeeV1.java deleted file mode 100644 index 57c7517767..0000000000 --- a/group01/765324639/src/zavier/week04/coderising/jvm/test/EmployeeV1.java +++ /dev/null @@ -1,31 +0,0 @@ -package zavier.week04.coderising.jvm.test; - -public class EmployeeV1 { - - - private String name; - private int age; - - public EmployeeV1(String name, int age) { - this.name = name; - this.age = age; - } - - public void setName(String name) { - this.name = name; - } - - public void setAge(int age) { - this.age = age; - } - - public void sayHello() { - System.out.println("Hello , this is class Employee "); - } - - public static void main(String[] args) { - EmployeeV1 p = new EmployeeV1("Andy", 29); - p.sayHello(); - - } -} diff --git a/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrame.java b/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrame.java deleted file mode 100644 index eb82d94d5e..0000000000 --- a/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrame.java +++ /dev/null @@ -1,177 +0,0 @@ -package zavier.week04.coderising.linklist; - -/** - * 用双向链表实现LRU算法 - * - * @author liuxin - * - */ -public class LRUPageFrame { - - private static class Node { - Node prev; - Node next; - int pageNum; - - Node(int pageNum) { - this.pageNum = pageNum; - } - } - - private int capacity; - private int size; - - private Node first;// 链表头 - private Node last;// 链表尾 - - public LRUPageFrame(int capacity) { - this.capacity = capacity; - } - - /** - * 获取缓存中对象 - * - * @param key - * @return - */ - public void access(int pageNum) { - if (isEmpty()) { - initFirstNode(pageNum); - return; - } - - if (contains(pageNum)) { - moveToFirst(pageNum); - } else { - insert(pageNum); - } - } - - private void initFirstNode(int pageNum) { - Node node = new Node(pageNum); - first = last = node; - size++; - } - - private void moveToFirst(int pageNum) { - if (isFirst(pageNum)) { - return; - } - if (isLast(pageNum)) { - moveLastToFirst(); - } else { - moveMidToFirst(pageNum); - } - } - - private void moveLastToFirst() { - Node temp = last; - - removeLast(); - - addToFirst(temp); - } - - private void addToFirst(Node temp) { - temp.next = first; - first.prev = temp; - first = temp; - size++; - } - - private void moveMidToFirst(int pageNum) { - Node node = removeMidNode(pageNum); - addToFirst(node); - } - - private Node removeMidNode(int pageNum) { - Node temp = getNode(pageNum); - temp.prev.next = temp.next; - temp.next.prev = temp.prev; - - temp.next = null; - temp.prev = null; - - size--; - - return temp; - } - - private void insert(int pageNum) { - if (isFill()) { - removeLast(); - } - insertToFirst(pageNum); - } - - private void removeLast() { - last = last.prev; - last.next = null; - size--; - } - - private void insertToFirst(int pageNum) { - Node node = new Node(pageNum); - - addToFirst(node); - } - - private boolean contains(int pageNum) { - return indexOf(pageNum) != -1; - } - - private int indexOf(int num) { - Node temp = first; - for (int i = 0; i < size; i++) { - if (temp.pageNum == num) { - return i; - } - temp = temp.next; - } - return -1; - } - - private Node getNode(int pageNum) { - Node temp; - temp = first; - for (int i = 0; i < size; i++) { - if (temp.pageNum == pageNum) { - break; - } - temp = temp.next; - } - return temp; - } - - private boolean isEmpty() { - return size == 0; - } - - private boolean isFirst(int pageNum) { - return first.pageNum == pageNum; - } - - private boolean isLast(int pageNum) { - return last.pageNum == pageNum; - } - - private boolean isFill() { - return size == capacity; - } - - @Override - public String toString() { - StringBuilder buffer = new StringBuilder(); - Node node = first; - while (node != null) { - buffer.append(node.pageNum); - - node = node.next; - if (node != null) { - buffer.append(","); - } - } - return buffer.toString(); - } - -} diff --git a/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrameTest.java b/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrameTest.java deleted file mode 100644 index 9b69297e21..0000000000 --- a/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrameTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package zavier.week04.coderising.linklist; - -import org.junit.Assert; -import org.junit.Test; - - -public class LRUPageFrameTest { - - @Test - public void testAccess() { - LRUPageFrame frame = new LRUPageFrame(3); - frame.access(7); - frame.access(0); - frame.access(1); - Assert.assertEquals("1,0,7", frame.toString()); - frame.access(2); - Assert.assertEquals("2,1,0", frame.toString()); - frame.access(0); - Assert.assertEquals("0,2,1", frame.toString()); - frame.access(0); - Assert.assertEquals("0,2,1", frame.toString()); - frame.access(3); - Assert.assertEquals("3,0,2", frame.toString()); - frame.access(0); - Assert.assertEquals("0,3,2", frame.toString()); - frame.access(4); - Assert.assertEquals("4,0,3", frame.toString()); - } - -} diff --git a/group01/895457260/code/src/main/java/algorithm/ArrayUtil.java b/group01/895457260/code/src/main/java/algorithm/ArrayUtil.java index bb5a25a93a..4ac933f4f3 100644 --- a/group01/895457260/code/src/main/java/algorithm/ArrayUtil.java +++ b/group01/895457260/code/src/main/java/algorithm/ArrayUtil.java @@ -96,7 +96,7 @@ public int[] merge(int[] array1, int[] array2) { return newArray; } /** - * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.size + size * 注意,老数组的元素在新数组中需要保持 * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 * [2,3,6,0,0,0] diff --git a/group01/895457260/code/src/main/java/algorithm/InfixExpr.java b/group01/895457260/code/src/main/java/algorithm/InfixExpr.java new file mode 100644 index 0000000000..1ddb740364 --- /dev/null +++ b/group01/895457260/code/src/main/java/algorithm/InfixExpr.java @@ -0,0 +1,140 @@ +package algorithm; + +import datastructure.basic.Stack; + +import java.util.ArrayList; +import java.util.List; + +public class InfixExpr { + + Stack numbers = new Stack(); + Stack operators = new Stack(); + + String expr = null; + + public InfixExpr(String expr) { + this.expr = expr; + operators.push("#"); + } + + public float evaluate() throws CalculateException { + numbers.clear(); + operators.clear(); + operators.push("#"); + + String[] split = split(expr); + String[] strs = new String[split.length + 1]; + strs[strs.length - 1] = "#"; + System.arraycopy(split, 0, strs, 0, split.length); + + for (int i = 0; !operators.isEmpty() && i < strs.length; ++i) { + String str = strs[i]; + try { + float number = Float.parseFloat(str); + putNumber(number); + } catch (NumberFormatException e) { + putOperator(str); + } + } + return numbers.isEmpty() ? 0 : (float) numbers.peek(); + } + + private String[] split(String expr) { + List list = new ArrayList<>(); + int startPos = 0; + for (int i = 0, j = 1; j < expr.length(); ++i, ++j) { + char cI = expr.charAt(i); + char cJ = expr.charAt(j); + if (isDigit(cI) ^ isDigit(cJ)) { + list.add(expr.substring(startPos, j)); + startPos = j; + } + } + list.add(expr.substring(startPos)); + return list.toArray(new String[list.size()]); + } + + private boolean isDigit(char c) { + return Character.isDigit(c) || c == '.'; + } + + private void putNumber(float num) { + numbers.push(num); + } + + private void putOperator(String op) throws CalculateException { + int compare = compare(op, (String) operators.peek()); + switch (compare) { + case 1: + operators.push(op); + break; + case 0: + operators.pop(); + break; + case -1: + float num1 = (float) numbers.pop(); + float num2 = (float) numbers.pop(); + String operator = (String) operators.pop(); + float result = calculate(num2, operator, num1); + numbers.push(result); + putOperator(op); + break; + } + } + + private float calculate(float num2, String op, float num1) throws CalculateException { + switch (op) { + case "+": + return num2 + num1; + case "-": + return num2 - num1; + case "*": + return num2 * num1; + case "/": + if (num1 != 0) { + return num2 / num1; + } + } + throw new CalculateException(); + } + + private int compare(String op, String peek) { + int opIndex = indexOf(op); + int peekIndex = indexOf(peek); + return table[opIndex][peekIndex]; + } + + private int indexOf(String op) { + switch (op) { + case "+": + return 0; + case "-": + return 1; + case "*": + return 2; + case "/": + return 3; + case "(": + return 4; + case ")": + return 5; + case "#": + return 6; + } + return 0; + } + + //优先级表 + private int[][] table = { + // + - * / ( ) # + {-1, -1, -1, -1, 1, -1, 1}, // + + {-1, -1, -1, -1, 1, -1, 1}, // - + { 1, 1, -1, -1, 1, -1, 1}, // * + { 1, 1, -1, -1, 1, -1, 1}, // / + { 1, 1, 1, 1, 1, -1, 1}, // ( + {-1, -1, -1, -1, -1, 0, 1}, // ) + {-1, -1, -1, -1, -1, -1, 0} // # + }; + + public static class CalculateException extends Exception {} +} diff --git a/group01/895457260/code/src/main/java/algorithm/StackUtil.java b/group01/895457260/code/src/main/java/algorithm/StackUtil.java new file mode 100644 index 0000000000..1b8ecf63de --- /dev/null +++ b/group01/895457260/code/src/main/java/algorithm/StackUtil.java @@ -0,0 +1,99 @@ +package algorithm; + +import datastructure.basic.Stack; + +import java.util.Arrays; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + Stack reverse = new Stack(); + while (!s.isEmpty()) { + reverse.push(s.pop()); + } + Stack reverseAgain = new Stack(); + while (!reverse.isEmpty()) { + reverseAgain.push(reverse.pop()); + } + while (!reverseAgain.isEmpty()) { + s.push(reverseAgain.pop()); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s, Object o) { + Stack temp = new Stack(); + while (!s.isEmpty()) { + Object pop = s.pop(); + if (!pop.equals(o)) { + temp.push(pop); + } + } + while (!temp.isEmpty()) { + s.push(temp.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s, int len) { + Stack temp = new Stack(); + for (int i = 0; i < len && !s.isEmpty(); ++i) { + temp.push(s.pop()); + } + Object[] result = new Object[temp.size()]; + for (int i = 0; i < result.length; ++i) { + result[i] = temp.pop(); + s.push(result[i]); + } + return result; + } + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + Stack brackets = new Stack(); + char[] chars = s.toCharArray(); + + for (char c : chars) { + if (isBracket(c)) { + if (!brackets.isEmpty() && isPair((Character) brackets.peek(), c)) { + brackets.pop(); + } else { + brackets.push(c); + } + } + } + return brackets.isEmpty(); + } + + private static boolean isBracket(char c) { + return c == '(' || c == ')' + || c == '[' || c == ']' + || c == '{' || c == '}'; + } + + private static boolean isPair(char left, char right) { + return (left == '(' && right == ')') + || (left == '[' && right == ']') + || (left == '{' && right == '}'); + } +} diff --git a/group01/895457260/code/src/main/java/datastructure/basic/Stack.java b/group01/895457260/code/src/main/java/datastructure/basic/Stack.java index ab4fc874ae..eeb9c7afba 100644 --- a/group01/895457260/code/src/main/java/datastructure/basic/Stack.java +++ b/group01/895457260/code/src/main/java/datastructure/basic/Stack.java @@ -29,4 +29,8 @@ public boolean isEmpty() { public int size() { return elementData.size(); } + + public void clear() { + elementData = new ArrayList(); + } } diff --git a/group01/895457260/code/src/main/java/jvm/ClassFileLoader.java b/group01/895457260/code/src/main/java/jvm/ClassFileLoader.java index 53e401c119..ade626ad83 100644 --- a/group01/895457260/code/src/main/java/jvm/ClassFileLoader.java +++ b/group01/895457260/code/src/main/java/jvm/ClassFileLoader.java @@ -1,9 +1,12 @@ package jvm; +import jvm.classfile.ClassFile; +import jvm.classfile.ClassParser; import jvm.exception.ClassDuplicateException; import jvm.exception.ClassNotExistsException; import jvm.exception.ReadClassException; import jvm.util.ArrayUtils; +import jvm.util.ByteUtils; import java.io.*; import java.util.ArrayList; @@ -69,12 +72,16 @@ public String getClassPath() { } boolean checkMagicNumber(byte[] bytes) { - String magicNumber = "CAFEBABE"; - String str = ""; - int byteNum = 4; - for (int i = 0; i < byteNum; ++i) { - str += Integer.toHexString(Byte.toUnsignedInt(bytes[i])); + String magicNumber = "cafebabe"; + String str = ByteUtils.toHexString(bytes, 0, 4); + return magicNumber.equals(str.toLowerCase()); + } + + public ClassFile load(String className) throws ReadClassException { + byte[] bytes = readBinaryCode(className); + if (checkMagicNumber(bytes)) { + return ClassParser.parse(bytes); } - return magicNumber.equals(str.toUpperCase()); + return null; } } diff --git a/group01/895457260/code/src/main/java/jvm/classfile/AccessFlag.java b/group01/895457260/code/src/main/java/jvm/classfile/AccessFlag.java new file mode 100644 index 0000000000..18c327fb0d --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/AccessFlag.java @@ -0,0 +1,30 @@ +package jvm.classfile; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class AccessFlag { + int flagValue; + + public AccessFlag() {} + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/ClassFile.java b/group01/895457260/code/src/main/java/jvm/classfile/ClassFile.java new file mode 100644 index 0000000000..41f983a086 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/ClassFile.java @@ -0,0 +1,75 @@ +package jvm.classfile; + + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.constant.item.impl.ClassInfo; +import jvm.classfile.field.Field; +import jvm.classfile.method.Method; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class ClassFile { + ClassIndex classIndex; + AccessFlag accessFlag; + ConstantPool constantPool; + int minorVersion; + int majorVersion; + List interfaces = new ArrayList<>(); + List fields = new ArrayList<>(); + List methods = new ArrayList<>(); + List attributes = new ArrayList<>(); + + public List getInterfaces() { + return this.interfaces; + } + public List getFields() { + return this.fields; + } + public List getMethods() { + return methods; + } + public List getAttributes() { + return attributes; + } + + public void print() { + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + System.out.println("Super Class Name:"+ getSuperClassName()); + } + + private String getClassName() { + int thisClassIndex = this.classIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + + private String getSuperClassName() { + ClassInfo superClass = (ClassInfo)this.getConstantPool() + .getConstantInfo(this.classIndex.getSuperClassIndex()); + return superClass.getClassName(); + } + + public int getMinorVersion() { + return minorVersion; + } + + public int getMajorVersion() { + return majorVersion; + } + + public ConstantPool getConstantPool() { + return constantPool; + } + + public ClassIndex getClzIndex() { + return classIndex; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/ClassIndex.java b/group01/895457260/code/src/main/java/jvm/classfile/ClassIndex.java new file mode 100644 index 0000000000..dc3891698d --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/ClassIndex.java @@ -0,0 +1,18 @@ +package jvm.classfile; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class ClassIndex { + int thisClass; + int superClass; + + public int getThisClassIndex() { + return thisClass; + } + + public int getSuperClassIndex() { + return superClass; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/ClassParser.java b/group01/895457260/code/src/main/java/jvm/classfile/ClassParser.java new file mode 100644 index 0000000000..fa3a07527d --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/ClassParser.java @@ -0,0 +1,113 @@ +package jvm.classfile; + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.attribute.parser.AttributeParser; +import jvm.classfile.constant.item.IReference; +import jvm.classfile.constant.item.impl.ClassInfo; +import jvm.classfile.constant.item.impl.CountConstant; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.classfile.constant.parser.ConstantParserFactory; +import jvm.classfile.field.Field; +import jvm.classfile.method.Method; +import jvm.util.ByteCodeIterator; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class ClassParser { + public static ClassFile parse(byte[] bytes) { + ClassFile classFile = new ClassFile(); + ByteCodeIterator iterator = new ByteCodeIterator(bytes); + + iterator.skip(4); // skip magic number + + classFile.minorVersion = parseMinorVersion(iterator); + classFile.majorVersion = parseMajorVersion(iterator); + classFile.constantPool = parseConstantPool(iterator); + classFile.accessFlag = parseAccessFlag(iterator); + classFile.classIndex = parseClassIndex(iterator); + parseInterfaces(classFile, iterator); + parseFields(classFile, iterator); + parseMethods(classFile, iterator); + parseAttributes(classFile, iterator); + linkConstantReferences(classFile); + return classFile; + } + + private static void parseAttributes(ClassFile classFile, ByteCodeIterator iterator) { + int count = iterator.nextU2ToInt(); + for (int i = 0; i < count; ++i) { + AttributeInfo attribute = AttributeParser.parse(iterator, classFile.constantPool); + classFile.attributes.add(attribute); + } + } + + private static int parseMinorVersion(ByteCodeIterator iterator) { + return iterator.nextU2ToInt(); + } + + private static int parseMajorVersion(ByteCodeIterator iterator) { + return iterator.nextU2ToInt(); + } + + private static ConstantPool parseConstantPool(ByteCodeIterator iterator) { + ConstantPool constantPool = new ConstantPool(); + + int count = iterator.nextU2ToInt(); + constantPool.addConstantInfo(new CountConstant(count)); + + for (int i = 1; i < count; ++i) { + int tag = iterator.nextU1ToInt(); + ConstantParser parser = ConstantParserFactory.get(tag); + constantPool.addConstantInfo(parser.parse(iterator)); + } + return constantPool; + } + + private static AccessFlag parseAccessFlag(ByteCodeIterator iterator) { + AccessFlag accessFlag = new AccessFlag(); + accessFlag.flagValue = iterator.nextU2ToInt(); + return accessFlag; + } + + private static ClassIndex parseClassIndex(ByteCodeIterator iterator) { + ClassIndex classIndex = new ClassIndex(); + classIndex.thisClass = iterator.nextU2ToInt(); + classIndex.superClass = iterator.nextU2ToInt(); + return classIndex; + } + + private static void parseInterfaces(ClassFile classFile, ByteCodeIterator iterator) { + int count = iterator.nextU2ToInt(); + ConstantPool constantPool = classFile.constantPool; + for (int i = 0; i < count; ++i) { + int index = iterator.nextU2ToInt(); + ClassInfo info = (ClassInfo) constantPool.getConstantInfo(index); + classFile.interfaces.add(info); + } + } + + private static void parseFields(ClassFile classFile, ByteCodeIterator iterator) { + int count = iterator.nextU2ToInt(); + for (int i = 0; i < count; ++i) { + classFile.fields.add(Field.parse(iterator, classFile.constantPool)); + } + } + + private static void parseMethods(ClassFile classFile, ByteCodeIterator iterator) { + int count = iterator.nextU2ToInt(); + for (int i = 0; i < count; ++i) { + classFile.methods.add(Method.parse(iterator, classFile.constantPool)); + } + } + + private static void linkConstantReferences(ClassFile classFile) { + ConstantPool constantPool = classFile.constantPool; + constantPool.forEach(c -> { + if (c instanceof IReference) { + ((IReference) c).linkReference(constantPool); + } + }); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/ConstantPool.java b/group01/895457260/code/src/main/java/jvm/classfile/ConstantPool.java new file mode 100644 index 0000000000..b077ad83a4 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/ConstantPool.java @@ -0,0 +1,30 @@ +package jvm.classfile; + +import jvm.classfile.constant.item.Constant; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class ConstantPool { + private List constantMap = new ArrayList<>(); + + public void forEach(Consumer action) { + constantMap.forEach(action); + } + + public int getSize() { + return constantMap.size() - 1; + } + + boolean addConstantInfo(Constant c) { + return constantMap.add(c); + } + public Constant getConstantInfo(int index) { + return constantMap.get(index); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/AttributeInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/AttributeInfo.java new file mode 100644 index 0000000000..595c12ac9b --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/AttributeInfo.java @@ -0,0 +1,18 @@ +package jvm.classfile.attribute.item; + +public abstract class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + + int attrNameIndex; + int attrLen; + + public AttributeInfo(int attrNameIndex, int attrLen) { + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/CodeAttr.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/CodeAttr.java new file mode 100644 index 0000000000..75c7383bd8 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/CodeAttr.java @@ -0,0 +1,38 @@ +package jvm.classfile.attribute.item.impl; + +import jvm.classfile.attribute.item.AttributeInfo; + +import java.util.ArrayList; +import java.util.List; + +public class CodeAttr extends AttributeInfo { + private int maxStack; + private int maxLocals; + private int codeLen; + private String code; + private List attributes = new ArrayList<>(); + //private ByteCodeCommand[] cmds ; + + //public ByteCodeCommand[] getCmds() { + // return cmds; + //} + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, + int codeLen, String code, List attributes /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + this.attributes = attributes; + //this.cmds = cmds; + } + + public String getCode() { + return code; + } + + public List getAttributes() { + return attributes; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/LineNumberTableAttr.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/LineNumberTableAttr.java new file mode 100644 index 0000000000..c2a75a95c5 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/LineNumberTableAttr.java @@ -0,0 +1,37 @@ +package jvm.classfile.attribute.item.impl; + +import jvm.classfile.attribute.item.AttributeInfo; + +import java.util.ArrayList; +import java.util.List; + +public class LineNumberTableAttr extends AttributeInfo { + private List items = new ArrayList<>(); + + public LineNumberTableAttr(int attrNameIndex, int attrLen, List items) { + super(attrNameIndex, attrLen); + this.items = items; + } + + public List getItems() { + return items; + } + + public static class LineNumberItem { + private int startPc; + private int lineNumber; + + public LineNumberItem(int startPc, int lineNumber) { + this.startPc = startPc; + this.lineNumber = lineNumber; + } + + public int getStartPc() { + return startPc; + } + + public int getLineNumber() { + return lineNumber; + } + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/LocalVariableTableAttr.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/LocalVariableTableAttr.java new file mode 100644 index 0000000000..fce15e7365 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/LocalVariableTableAttr.java @@ -0,0 +1,52 @@ +package jvm.classfile.attribute.item.impl; + +import jvm.classfile.attribute.item.AttributeInfo; + +import java.util.ArrayList; +import java.util.List; + +public class LocalVariableTableAttr extends AttributeInfo { + + List items = new ArrayList<>(); + + public LocalVariableTableAttr(int attrNameIndex, int attrLen, List items) { + super(attrNameIndex, attrLen); + this.items = items; + } + + public static class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + + public LocalVariableItem(int startPC, int length, int nameIndex, int descIndex, int index) { + this.startPC = startPC; + this.length = length; + this.nameIndex = nameIndex; + this.descIndex = descIndex; + this.index = index; + } + + public int getStartPC() { + return startPC; + } + + public int getLength() { + return length; + } + + public int getNameIndex() { + return nameIndex; + } + + public int getDescIndex() { + return descIndex; + } + + public int getIndex() { + return index; + } + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/SourceFileAttr.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/SourceFileAttr.java new file mode 100644 index 0000000000..55921f5035 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/SourceFileAttr.java @@ -0,0 +1,16 @@ +package jvm.classfile.attribute.item.impl; + +import jvm.classfile.attribute.item.AttributeInfo; + +/** + * Created by Haochen on 2017/4/13. + * TODO: + */ +public class SourceFileAttr extends AttributeInfo { + private int sourceFileIndex; + + public SourceFileAttr(int attrNameIndex, int attrLen, int sourceFileIndex) { + super(attrNameIndex, attrLen); + this.sourceFileIndex = sourceFileIndex; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/StackMapTableAttr.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/StackMapTableAttr.java new file mode 100644 index 0000000000..cda2709020 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/item/impl/StackMapTableAttr.java @@ -0,0 +1,12 @@ +package jvm.classfile.attribute.item.impl; + +import jvm.classfile.attribute.item.AttributeInfo; + +public class StackMapTableAttr extends AttributeInfo { + private String originalCode; + + public StackMapTableAttr(int attrNameIndex, int attrLen, String originalCode) { + super(attrNameIndex, attrLen); + this.originalCode = originalCode; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/AttributeInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/AttributeInfoParser.java new file mode 100644 index 0000000000..7ac80cf179 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/AttributeInfoParser.java @@ -0,0 +1,14 @@ +package jvm.classfile.attribute.parser; + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.ConstantPool; +import jvm.util.ByteCodeIterator; + +/** + * Created by Haochen on 2017/4/13. + * TODO: + */ +public interface AttributeInfoParser { + AttributeInfo parse(int attrNameIndex, int attrLen, + ByteCodeIterator iterator, ConstantPool constantPool); +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/AttributeParser.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/AttributeParser.java new file mode 100644 index 0000000000..e67850037b --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/AttributeParser.java @@ -0,0 +1,37 @@ +package jvm.classfile.attribute.parser; + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.ConstantPool; +import jvm.classfile.constant.item.impl.UTF8Info; +import jvm.util.ByteCodeIterator; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Created by Haochen on 2017/4/12. + * TODO: + */ +public class AttributeParser { + public static AttributeInfo parse(ByteCodeIterator iterator, ConstantPool constantPool) { + int nameIndex = iterator.nextU2ToInt(); + String name = ((UTF8Info) constantPool.getConstantInfo(nameIndex)).getValue(); + int length = iterator.nextU4ToInt(); + + String className = AttributeParser.class.getPackage().getName() + + ".impl." + name + "Parser"; + try { + Class clazz = Class.forName(className); + Method parse = clazz.getMethod("parse", + int.class, int.class, ByteCodeIterator.class, ConstantPool.class); + byte[] bytes = iterator.getBytes(length); + ByteCodeIterator subIterator = new ByteCodeIterator(bytes); + return (AttributeInfo) parse.invoke(clazz.newInstance(), + nameIndex, length, subIterator, constantPool); + } catch (ClassNotFoundException | NoSuchMethodException + | IllegalAccessException | InvocationTargetException | InstantiationException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/CodeParser.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/CodeParser.java new file mode 100644 index 0000000000..2ee74f020a --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/CodeParser.java @@ -0,0 +1,36 @@ +package jvm.classfile.attribute.parser.impl; + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.attribute.parser.AttributeParser; +import jvm.classfile.attribute.item.impl.CodeAttr; +import jvm.classfile.attribute.parser.AttributeInfoParser; +import jvm.classfile.ConstantPool; +import jvm.util.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Haochen on 2017/4/13. + * TODO: + */ +public class CodeParser implements AttributeInfoParser { + @Override + public AttributeInfo parse(int attrNameIndex, int attrLen, + ByteCodeIterator iterator, ConstantPool constantPool) { + int maxStack = iterator.nextU2ToInt(); + int maxLocals = iterator.nextU2ToInt(); + int codeLen = iterator.nextU4ToInt(); + String code = iterator.nextHexString(codeLen); + + int exceptionTableLen = iterator.nextU2ToInt(); + iterator.skip(exceptionTableLen * 8); + + int attrCount = iterator.nextU2ToInt(); + List attributes = new ArrayList<>(); + for (int i = 0; i < attrCount; ++i) { + attributes.add(AttributeParser.parse(iterator, constantPool)); + } + return new CodeAttr(attrNameIndex, attrLen, maxStack, maxLocals, codeLen, code, attributes); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/LineNumberTableParser.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/LineNumberTableParser.java new file mode 100644 index 0000000000..8586ada746 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/LineNumberTableParser.java @@ -0,0 +1,33 @@ +package jvm.classfile.attribute.parser.impl; + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.attribute.item.impl.LineNumberTableAttr; +import jvm.classfile.attribute.parser.AttributeInfoParser; +import jvm.classfile.ConstantPool; +import jvm.util.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Haochen on 2017/4/13. + * TODO: + */ +public class LineNumberTableParser implements AttributeInfoParser { + @Override + public AttributeInfo parse(int attrNameIndex, int attrLen, + ByteCodeIterator iterator, ConstantPool constantPool) { + int tableLength = iterator.nextU2ToInt(); + + List items = new ArrayList<>(); + + for (int i = 0; i < tableLength; ++i) { + int startPC = iterator.nextU2ToInt(); + int lineNumber = iterator.nextU2ToInt(); + LineNumberTableAttr.LineNumberItem item = + new LineNumberTableAttr.LineNumberItem(startPC, lineNumber); + items.add(item); + } + return new LineNumberTableAttr(attrNameIndex, attrLen, items); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/LocalVariableTableParser.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/LocalVariableTableParser.java new file mode 100644 index 0000000000..9507ae3f37 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/LocalVariableTableParser.java @@ -0,0 +1,37 @@ +package jvm.classfile.attribute.parser.impl; + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.attribute.item.impl.LocalVariableTableAttr; +import jvm.classfile.attribute.parser.AttributeInfoParser; +import jvm.classfile.ConstantPool; +import jvm.util.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Haochen on 2017/4/13. + * TODO: + */ +public class LocalVariableTableParser implements AttributeInfoParser { + @Override + public AttributeInfo parse(int attrNameIndex, int attrLen, + ByteCodeIterator iterator, ConstantPool constantPool) { + int tableLen = iterator.nextU2ToInt(); + + List items = new ArrayList<>(); + + for (int i = 0; i < tableLen; ++i) { + int startPC = iterator.nextU2ToInt(); + int length = iterator.nextU2ToInt(); + int nameIndex = iterator.nextU2ToInt(); + int descIndex = iterator.nextU2ToInt(); + int index = iterator.nextU2ToInt(); + LocalVariableTableAttr.LocalVariableItem item = + new LocalVariableTableAttr.LocalVariableItem( + startPC, length, nameIndex, descIndex, index); + items.add(item); + } + return new LocalVariableTableAttr(attrNameIndex, attrLen ,items); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/SourceFileParser.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/SourceFileParser.java new file mode 100644 index 0000000000..0c8561b21c --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/SourceFileParser.java @@ -0,0 +1,20 @@ +package jvm.classfile.attribute.parser.impl; + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.attribute.item.impl.SourceFileAttr; +import jvm.classfile.attribute.parser.AttributeInfoParser; +import jvm.classfile.ConstantPool; +import jvm.util.ByteCodeIterator; + +/** + * Created by Haochen on 2017/4/13. + * TODO: + */ +public class SourceFileParser implements AttributeInfoParser { + @Override + public AttributeInfo parse(int attrNameIndex, int attrLen, + ByteCodeIterator iterator, ConstantPool constantPool) { + int sourceFileIndex = iterator.nextU2ToInt(); + return new SourceFileAttr(attrNameIndex, attrLen, sourceFileIndex); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/StackMapTableParser.java b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/StackMapTableParser.java new file mode 100644 index 0000000000..087edcffcf --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/attribute/parser/impl/StackMapTableParser.java @@ -0,0 +1,25 @@ +package jvm.classfile.attribute.parser.impl; + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.attribute.item.impl.StackMapTableAttr; +import jvm.classfile.attribute.parser.AttributeInfoParser; +import jvm.classfile.ConstantPool; +import jvm.util.ByteCodeIterator; + +/** + * Created by Haochen on 2017/4/13. + * TODO: + */ +public class StackMapTableParser implements AttributeInfoParser { + @Override + public AttributeInfo parse(int attrNameIndex, int attrLen, + ByteCodeIterator iterator, ConstantPool constantPool) { + int index = iterator.nextU2ToInt(); + int len = iterator.nextU4ToInt(); + + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + String code = iterator.nextHexString(len); + + return new StackMapTableAttr(index, len, code); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/Constant.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/Constant.java new file mode 100644 index 0000000000..c83fbfbb28 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/Constant.java @@ -0,0 +1,9 @@ +package jvm.classfile.constant.item; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public interface Constant { + int size(); +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/IReference.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/IReference.java new file mode 100644 index 0000000000..89a819aa96 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/IReference.java @@ -0,0 +1,11 @@ +package jvm.classfile.constant.item; + +import jvm.classfile.ConstantPool; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public interface IReference { + void linkReference(ConstantPool constantPool); +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/ClassInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/ClassInfo.java new file mode 100644 index 0000000000..84657cd7e4 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/ClassInfo.java @@ -0,0 +1,39 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.ConstantPool; +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.IReference; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class ClassInfo implements Constant, IReference { + private int nameIndex; + private String className; + + public ClassInfo(int nameIndex) { + this.nameIndex = nameIndex; + } + + @Override + public int size() { + return 3; + } + + @Override + public void linkReference(ConstantPool constantPool) { + Constant constant = constantPool.getConstantInfo(getUtf8Index()); + if (constant instanceof UTF8Info) { + this.className = ((UTF8Info) constant).getValue(); + } + } + + public int getUtf8Index() { + return nameIndex; + } + + public String getClassName() { + return className; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/CountConstant.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/CountConstant.java new file mode 100644 index 0000000000..1d671fcbda --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/CountConstant.java @@ -0,0 +1,24 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class CountConstant implements Constant { + private int count; + + public CountConstant(int count) { + this.count = count; + } + + @Override + public int size() { + return 2; + } + + public int getCount() { + return count; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/DoubleInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/DoubleInfo.java new file mode 100644 index 0000000000..8fa38452f6 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/DoubleInfo.java @@ -0,0 +1,30 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class DoubleInfo implements Constant { + private byte[] highBytes; + private byte[] lowBytes; + + public DoubleInfo(byte[] highBytes, byte[] lowBytes) { + this.highBytes = highBytes; + this.lowBytes = lowBytes; + } + + @Override + public int size() { + return 9; + } + + public byte[] getHighBytes() { + return highBytes; + } + + public byte[] getLowBytes() { + return lowBytes; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/FieldRefInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/FieldRefInfo.java new file mode 100644 index 0000000000..a7f51f51ba --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/FieldRefInfo.java @@ -0,0 +1,30 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class FieldRefInfo implements Constant { + private int classIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(int classIndex, int nameAndTypeIndex) { + this.classIndex = classIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public int size() { + return 5; + } + + public int getClassIndex() { + return classIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/FloatInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/FloatInfo.java new file mode 100644 index 0000000000..1368c07674 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/FloatInfo.java @@ -0,0 +1,24 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class FloatInfo implements Constant { + private byte[] bytes; + + public FloatInfo(byte[] bytes) { + this.bytes = bytes; + } + + @Override + public int size() { + return 5; + } + + public byte[] getBytes() { + return bytes; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/IntegerInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/IntegerInfo.java new file mode 100644 index 0000000000..e345f94994 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/IntegerInfo.java @@ -0,0 +1,24 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class IntegerInfo implements Constant { + private byte[] bytes; + + public IntegerInfo(byte[] bytes) { + this.bytes = bytes; + } + + @Override + public int size() { + return 5; + } + + public byte[] getBytes() { + return bytes; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/InterfaceMethodRefInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/InterfaceMethodRefInfo.java new file mode 100644 index 0000000000..e22f8d4a45 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/InterfaceMethodRefInfo.java @@ -0,0 +1,30 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class InterfaceMethodRefInfo implements Constant { + private int classIndex; + private int nameAndTypeIndex; + + public InterfaceMethodRefInfo(int classIndex, int nameAndTypeIndex) { + this.classIndex = classIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public int size() { + return 5; + } + + public int getClassIndex() { + return classIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/InvokeDynamicInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/InvokeDynamicInfo.java new file mode 100644 index 0000000000..91caadbb46 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/InvokeDynamicInfo.java @@ -0,0 +1,30 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class InvokeDynamicInfo implements Constant { + private int bootstrapMethodAttrIndex; + private int nameAndTypeIndex; + + public InvokeDynamicInfo(int bootstrapMethodAttrIndex, int nameAndTypeIndex) { + this.bootstrapMethodAttrIndex = bootstrapMethodAttrIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public int size() { + return 5; + } + + public int getBootstrapMethodAttrIndex() { + return bootstrapMethodAttrIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/LongInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/LongInfo.java new file mode 100644 index 0000000000..c740e39f30 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/LongInfo.java @@ -0,0 +1,30 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class LongInfo implements Constant { + private byte[] highBytes; + private byte[] lowBytes; + + public LongInfo(byte[] highBytes, byte[] lowBytes) { + this.highBytes = highBytes; + this.lowBytes = lowBytes; + } + + @Override + public int size() { + return 9; + } + + public byte[] getHighBytes() { + return highBytes; + } + + public byte[] getLowBytes() { + return lowBytes; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/MethodHandleInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/MethodHandleInfo.java new file mode 100644 index 0000000000..c7b6fbe4ac --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/MethodHandleInfo.java @@ -0,0 +1,30 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class MethodHandleInfo implements Constant { + private int referenceKind; + private int referenceIndex; + + public MethodHandleInfo(int referenceKind, int referenceIndex) { + this.referenceKind = referenceKind; + this.referenceIndex = referenceIndex; + } + + @Override + public int size() { + return 4; + } + + public int getReferenceKind() { + return referenceKind; + } + + public int getReferenceIndex() { + return referenceIndex; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/MethodRefInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/MethodRefInfo.java new file mode 100644 index 0000000000..c52903956c --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/MethodRefInfo.java @@ -0,0 +1,30 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class MethodRefInfo implements Constant { + private int classIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(int classIndex, int nameAndTypeIndex) { + this.classIndex = classIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public int size() { + return 5; + } + + public int getClassInfoIndex() { + return classIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/MethodTypeInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/MethodTypeInfo.java new file mode 100644 index 0000000000..9b7e7cba1f --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/MethodTypeInfo.java @@ -0,0 +1,24 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class MethodTypeInfo implements Constant { + private int descriptorIndex; + + public MethodTypeInfo(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } + + @Override + public int size() { + return 3; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/NameAndTypeInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/NameAndTypeInfo.java new file mode 100644 index 0000000000..c783b969e7 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/NameAndTypeInfo.java @@ -0,0 +1,38 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class NameAndTypeInfo implements Constant { + private int nameIndex; + private int descriptorIndex; + + public NameAndTypeInfo(int nameIndex, int descriptorIndex) { + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + @Override + public int size() { + return 5; + } + + public int getNameIndex() { + return nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public int getIndex1() { + return nameIndex; + } + + public int getIndex2() { + return descriptorIndex; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/StringInfo.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/StringInfo.java new file mode 100644 index 0000000000..6e7548db05 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/StringInfo.java @@ -0,0 +1,33 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.ConstantPool; +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.IReference; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class StringInfo implements Constant, IReference { + private int stringIndex; + private String value; + + public StringInfo(int stringIndex) { + this.stringIndex = stringIndex; + } + + @Override + public int size() { + return 3; + } + + public String getValue() { + return value; + } + + @Override + public void linkReference(ConstantPool constantPool) { + UTF8Info info = (UTF8Info) constantPool.getConstantInfo(stringIndex); + value = info.getValue(); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/UTF8Info.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/UTF8Info.java new file mode 100644 index 0000000000..86d139fb7c --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/item/impl/UTF8Info.java @@ -0,0 +1,36 @@ +package jvm.classfile.constant.item.impl; + +import jvm.classfile.constant.item.Constant; + +import java.io.UnsupportedEncodingException; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class UTF8Info implements Constant { + private int length; + private String value; + + public UTF8Info(int length, byte[] bytes) { + this.length = length; + try { + this.value = new String(bytes, "utf8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + + @Override + public int size() { + return 3 + length; + } + + public int getLength() { + return length; + } + + public String getValue() { + return value; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/ConstantParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/ConstantParser.java new file mode 100644 index 0000000000..9902724df0 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/ConstantParser.java @@ -0,0 +1,12 @@ +package jvm.classfile.constant.parser; + +import jvm.classfile.constant.item.Constant; +import jvm.util.ByteCodeIterator; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public interface ConstantParser { + Constant parse(ByteCodeIterator iterator); +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/ConstantParserFactory.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/ConstantParserFactory.java new file mode 100644 index 0000000000..56583b2df7 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/ConstantParserFactory.java @@ -0,0 +1,60 @@ +package jvm.classfile.constant.parser; + +import jvm.classfile.constant.parser.impl.*; +import jvm.util.ByteUtils; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class ConstantParserFactory { + private static final int CONSTANT_CLASS = 7; + private static final int CONSTANT_FIELD_REF = 9; + private static final int CONSTANT_METHOD_REF = 10; + private static final int CONSTANT_INTERFACE_METHOD_REF = 11; + private static final int CONSTANT_STRING = 8; + private static final int CONSTANT_INTEGER = 3; + private static final int CONSTANT_FLOAT = 4; + private static final int CONSTANT_LONG = 5; + private static final int CONSTANT_DOUBLE = 6; + private static final int CONSTANT_NAME_AND_TYPE = 12; + private static final int CONSTANT_UTF8 = 1; + private static final int CONSTANT_METHOD_HANDLE = 15; + private static final int CONSTANT_METHOD_TYPE = 16; + private static final int CONSTANT_INVOKE_DYNAMIC = 18; + + public static ConstantParser get(int type) { + switch (type) { + case CONSTANT_CLASS: + return new ClassInfoParser(); + case CONSTANT_FIELD_REF: + return new FieldRefInfoParser(); + case CONSTANT_METHOD_REF: + return new MethodRefInfoParser(); + case CONSTANT_INTERFACE_METHOD_REF: + return new InterfaceMethodRefInfoParser(); + case CONSTANT_STRING: + return new StringInfoParser(); + case CONSTANT_INTEGER: + return new IntegerInfoParser(); + case CONSTANT_FLOAT: + return new FloatInfoParser(); + case CONSTANT_LONG: + return new LongInfoParser(); + case CONSTANT_DOUBLE: + return new DoubleInfoParser(); + case CONSTANT_NAME_AND_TYPE: + return new NameAndTypeInfoParser(); + case CONSTANT_UTF8: + return new UTF8InfoParser(); + case CONSTANT_METHOD_HANDLE: + return new MethodHandleInfoParser(); + case CONSTANT_METHOD_TYPE: + return new MethodTypeInfoParser(); + case CONSTANT_INVOKE_DYNAMIC: + return new InvokeDynamicInfoParser(); + default: + return null; + } + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/ClassInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/ClassInfoParser.java new file mode 100644 index 0000000000..78b9a3f03f --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/ClassInfoParser.java @@ -0,0 +1,18 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.ClassInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; +import jvm.util.ByteUtils; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class ClassInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + return new ClassInfo(iterator.nextU2ToInt()); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/DoubleInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/DoubleInfoParser.java new file mode 100644 index 0000000000..72caf2f799 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/DoubleInfoParser.java @@ -0,0 +1,19 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.DoubleInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class DoubleInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + byte[] high = iterator.getBytes(4); + byte[] low = iterator.getBytes(4); + return new DoubleInfo(high, low); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/FieldRefInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/FieldRefInfoParser.java new file mode 100644 index 0000000000..1a3feac724 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/FieldRefInfoParser.java @@ -0,0 +1,20 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.FieldRefInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; +import jvm.util.ByteUtils; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class FieldRefInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + int classIndex = iterator.nextU2ToInt(); + int nameAndTypeIndex = iterator.nextU2ToInt(); + return new FieldRefInfo(classIndex, nameAndTypeIndex); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/FloatInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/FloatInfoParser.java new file mode 100644 index 0000000000..bedd2fd963 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/FloatInfoParser.java @@ -0,0 +1,17 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.FloatInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class FloatInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + return new FloatInfo(iterator.getBytes(4)); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/IntegerInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/IntegerInfoParser.java new file mode 100644 index 0000000000..ac316580d7 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/IntegerInfoParser.java @@ -0,0 +1,17 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.IntegerInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class IntegerInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + return new IntegerInfo(iterator.getBytes(4)); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/InterfaceMethodRefInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/InterfaceMethodRefInfoParser.java new file mode 100644 index 0000000000..65a9ff4fdf --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/InterfaceMethodRefInfoParser.java @@ -0,0 +1,21 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.FieldRefInfo; +import jvm.classfile.constant.item.impl.InterfaceMethodRefInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; +import jvm.util.ByteUtils; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class InterfaceMethodRefInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + int classIndex = iterator.nextU2ToInt(); + int nameAndTypeIndex = iterator.nextU2ToInt(); + return new InterfaceMethodRefInfo(classIndex, nameAndTypeIndex); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/InvokeDynamicInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/InvokeDynamicInfoParser.java new file mode 100644 index 0000000000..1f8e5a3809 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/InvokeDynamicInfoParser.java @@ -0,0 +1,20 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.InvokeDynamicInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; +import jvm.util.ByteUtils; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class InvokeDynamicInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + int bootstrapMethodAttrIndex = iterator.nextU2ToInt(); + int nameAndTypeIndex = iterator.nextU2ToInt(); + return new InvokeDynamicInfo(bootstrapMethodAttrIndex, nameAndTypeIndex); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/LongInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/LongInfoParser.java new file mode 100644 index 0000000000..f58c092665 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/LongInfoParser.java @@ -0,0 +1,20 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.DoubleInfo; +import jvm.classfile.constant.item.impl.LongInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class LongInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + byte[] high = iterator.getBytes(4); + byte[] low = iterator.getBytes(4); + return new LongInfo(high, low); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/MethodHandleInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/MethodHandleInfoParser.java new file mode 100644 index 0000000000..9bff9c4285 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/MethodHandleInfoParser.java @@ -0,0 +1,20 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.MethodHandleInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; +import jvm.util.ByteUtils; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class MethodHandleInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + int referenceKind = iterator.nextU1ToInt(); + int referenceIndex = iterator.nextU2ToInt(); + return new MethodHandleInfo(referenceKind, referenceIndex); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/MethodRefInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/MethodRefInfoParser.java new file mode 100644 index 0000000000..1dbe7f85c6 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/MethodRefInfoParser.java @@ -0,0 +1,21 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.FieldRefInfo; +import jvm.classfile.constant.item.impl.MethodRefInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; +import jvm.util.ByteUtils; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class MethodRefInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + int classIndex = iterator.nextU2ToInt(); + int nameAndTypeIndex = iterator.nextU2ToInt(); + return new MethodRefInfo(classIndex, nameAndTypeIndex); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/MethodTypeInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/MethodTypeInfoParser.java new file mode 100644 index 0000000000..37a59f6422 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/MethodTypeInfoParser.java @@ -0,0 +1,19 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.MethodTypeInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; +import jvm.util.ByteUtils; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class MethodTypeInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + int descriptorIndex = iterator.nextU2ToInt(); + return new MethodTypeInfo(descriptorIndex); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/NameAndTypeInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/NameAndTypeInfoParser.java new file mode 100644 index 0000000000..3472f87f56 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/NameAndTypeInfoParser.java @@ -0,0 +1,20 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.NameAndTypeInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; +import jvm.util.ByteUtils; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class NameAndTypeInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + int nameIndex = iterator.nextU2ToInt(); + int descriptorIndex = iterator.nextU2ToInt(); + return new NameAndTypeInfo(nameIndex, descriptorIndex); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/StringInfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/StringInfoParser.java new file mode 100644 index 0000000000..b29ccdf4aa --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/StringInfoParser.java @@ -0,0 +1,18 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.StringInfo; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; +import jvm.util.ByteUtils; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class StringInfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + return new StringInfo(iterator.nextU2ToInt()); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/UTF8InfoParser.java b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/UTF8InfoParser.java new file mode 100644 index 0000000000..58aa699c24 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/constant/parser/impl/UTF8InfoParser.java @@ -0,0 +1,19 @@ +package jvm.classfile.constant.parser.impl; + +import jvm.classfile.constant.item.Constant; +import jvm.classfile.constant.item.impl.UTF8Info; +import jvm.classfile.constant.parser.ConstantParser; +import jvm.util.ByteCodeIterator; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class UTF8InfoParser implements ConstantParser { + @Override + public Constant parse(ByteCodeIterator iterator) { + int length = iterator.nextU2ToInt(); + byte[] array = iterator.getBytes(length); + return new UTF8Info(length, array); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/field/Field.java b/group01/895457260/code/src/main/java/jvm/classfile/field/Field.java new file mode 100644 index 0000000000..dcf6975543 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/field/Field.java @@ -0,0 +1,65 @@ +package jvm.classfile.field; + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.attribute.parser.AttributeParser; +import jvm.classfile.ConstantPool; +import jvm.classfile.constant.item.impl.UTF8Info; +import jvm.util.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + private ConstantPool constantPool; + private List attributes = new ArrayList<>(); + + public Field(int accessFlag, int nameIndex, int descriptorIndex, ConstantPool constantPool) { + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.constantPool = constantPool; + } + + public static Field parse(ByteCodeIterator iterator, ConstantPool constantPool) { + int access = iterator.nextU2ToInt(); + int name = iterator.nextU2ToInt(); + int descriptor = iterator.nextU2ToInt(); + int attrCount = iterator.nextU2ToInt(); + + Field result = new Field(access, name, descriptor, constantPool); + for (int i = 0; i < attrCount; ++i) { + result.attributes.add(AttributeParser.parse(iterator, constantPool)); + } + return result; + } + + @Override + public String toString() { + String name = ((UTF8Info) constantPool.getConstantInfo(nameIndex)).getValue(); + String desc = ((UTF8Info) constantPool.getConstantInfo(descriptorIndex)).getValue(); + return name + ":" + desc; + } + + public int getAccessFlag() { + return accessFlag; + } + + public int getNameIndex() { + return nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public ConstantPool getConstantPool() { + return constantPool; + } + + public List getAttributes() { + return attributes; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/classfile/method/Method.java b/group01/895457260/code/src/main/java/jvm/classfile/method/Method.java new file mode 100644 index 0000000000..6068124fa3 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/classfile/method/Method.java @@ -0,0 +1,57 @@ +package jvm.classfile.method; + +import jvm.classfile.attribute.item.AttributeInfo; +import jvm.classfile.attribute.parser.AttributeParser; +import jvm.classfile.ConstantPool; +import jvm.util.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + + +public class Method { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + private ConstantPool constantPool; + private List attributes = new ArrayList<>(); + + public Method(int accessFlag, int nameIndex, int descriptorIndex, ConstantPool constantPool) { + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.constantPool = constantPool; + } + + public static Method parse(ByteCodeIterator iterator, ConstantPool constantPool) { + int access = iterator.nextU2ToInt(); + int name = iterator.nextU2ToInt(); + int descriptor = iterator.nextU2ToInt(); + int attrCount = iterator.nextU2ToInt(); + Method result = new Method(access, name, descriptor, constantPool); + for (int i = 0; i < attrCount; ++i) { + result.attributes.add(AttributeParser.parse(iterator, constantPool)); + } + return result; + } + + public int getAccessFlag() { + return accessFlag; + } + + public ConstantPool getConstantPool() { + return constantPool; + } + + public int getNameIndex() { + return nameIndex; + } + + public List getAttributes() { + return attributes; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/util/ByteCodeIterator.java b/group01/895457260/code/src/main/java/jvm/util/ByteCodeIterator.java new file mode 100644 index 0000000000..a385aee580 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/util/ByteCodeIterator.java @@ -0,0 +1,70 @@ +package jvm.util; + +import java.util.Arrays; + +public class ByteCodeIterator { + private byte[] codes; + private int pos = 0; + + public ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public byte[] getBytes(int len) { + if (pos + len > codes.length) { + throw new ArrayIndexOutOfBoundsException(); + } + + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos += len; + return data; + } + + public int currentIndex() { + return pos; + } + + public int nextU1ToInt() { + return nextInt(1); + } + + public int nextU2ToInt() { + return nextInt(2); + } + + public int nextU4ToInt() { + return nextInt(4); + } + + public String nextU4ToHexString() { + return nextHexString(4); + } + + public String nextHexString(int byteCount) { + String result = ByteUtils.toHexString(codes, pos, byteCount).toLowerCase(); + pos += byteCount; + return result; + } + + public int nextInt(int byteCount) { + int result = ByteUtils.toInt(codes, pos, byteCount); + pos += byteCount; + return result; + } + + public void skip(int n) { + this.pos += n; + } + + public void back(int n) { + this.pos -= n; + } + + public void seekTo(int n) { + this.pos = n; + } + + public void reset() { + this.pos = 0; + } +} diff --git a/group01/895457260/code/src/main/java/jvm/util/ByteUtils.java b/group01/895457260/code/src/main/java/jvm/util/ByteUtils.java new file mode 100644 index 0000000000..3a0e1fc0b6 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/util/ByteUtils.java @@ -0,0 +1,19 @@ +package jvm.util; + +/** + * Created by Haochen on 2017/4/9. + * TODO: + */ +public class ByteUtils { + public static String toHexString(byte[] bytes, int off, int len) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < len; ++i) { + builder.append(Integer.toHexString(Byte.toUnsignedInt(bytes[off + i]))); + } + return builder.toString(); + } + + public static int toInt(byte[] bytes, int off, int len) { + return Integer.parseInt(toHexString(bytes, off, len), 16); + } +} diff --git a/group01/895457260/code/src/test/java/algorithm/InfixExprTest.java b/group01/895457260/code/src/test/java/algorithm/InfixExprTest.java new file mode 100644 index 0000000000..34480d6db7 --- /dev/null +++ b/group01/895457260/code/src/test/java/algorithm/InfixExprTest.java @@ -0,0 +1,48 @@ +package algorithm; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class InfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() throws InfixExpr.CalculateException { + //InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); + { + InfixExpr expr = new InfixExpr("2+3*4+5"); + Assert.assertEquals(19.0, expr.evaluate(), 0.001f); + } + { + InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); + Assert.assertEquals(100.0, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("3*20/2"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("20/2*3"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("10-30+50"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + } + +} diff --git a/group01/895457260/code/src/test/java/algorithm/StackUtilTest.java b/group01/895457260/code/src/test/java/algorithm/StackUtilTest.java new file mode 100644 index 0000000000..b66065dd4e --- /dev/null +++ b/group01/895457260/code/src/test/java/algorithm/StackUtilTest.java @@ -0,0 +1,99 @@ +package algorithm; + +import datastructure.basic.Stack; +import org.junit.Assert; +import org.junit.Test; +import org.junit.Before; +import org.junit.After; + +import java.util.Arrays; + +/** + * StackUtil Tester. + * + * @author + * @version 1.0 + * @since
四月 9, 2017
+ */ +public class StackUtilTest { + + @Before + public void before() throws Exception { + } + + @After + public void after() throws Exception { + } + + private Stack build(Object... args) { + Stack stack = new Stack(); + Arrays.stream(args).forEach(stack::push); + return stack; + } + + private Object[] toArray(Stack stack) { + Object[] array = new Object[stack.size()]; + for (int i = array.length - 1; i >= 0; --i) { + array[i] = stack.pop(); + } + Arrays.stream(array).forEach(stack::push); + return array; + } + + /** + * Method: reverse(Stack s) + */ + @Test + public void testReverse() throws Exception { +//TODO: Test goes here... + Stack stack = build(1, 3, 5, 7, 9); + StackUtil.reverse(stack); + Assert.assertArrayEquals(new Object[] {9, 7, 5, 3, 1}, toArray(stack)); + } + + /** + * Method: remove(Stack s, Object o) + */ + @Test + public void testRemove() throws Exception { +//TODO: Test goes here... + Stack stack = build(1, 3, 5, 7, 9, 11, 13); + StackUtil.remove(stack, 0); + Assert.assertArrayEquals(new Object[] {1, 3, 5, 7, 9, 11, 13}, toArray(stack)); + StackUtil.remove(stack, 1); + Assert.assertArrayEquals(new Object[] {3, 5, 7, 9, 11, 13}, toArray(stack)); + StackUtil.remove(stack, 13); + Assert.assertArrayEquals(new Object[] {3, 5, 7, 9, 11}, toArray(stack)); + StackUtil.remove(stack, 7); + Assert.assertArrayEquals(new Object[] {3, 5, 9, 11}, toArray(stack)); + } + + /** + * Method: getTop(Stack s, int len) + */ + @Test + public void testGetTop() throws Exception { +//TODO: Test goes here... + Stack stack = build(1, 3, 5); + Object[] array = toArray(stack); + Assert.assertArrayEquals(new Object[] {}, StackUtil.getTop(stack, 0)); + Assert.assertArrayEquals(new Object[] {1, 3, 5}, array); + Assert.assertArrayEquals(new Object[] {3, 5}, StackUtil.getTop(stack, 2)); + Assert.assertArrayEquals(new Object[] {1, 3, 5}, array); + Assert.assertArrayEquals(new Object[] {1, 3, 5}, StackUtil.getTop(stack, 3)); + Assert.assertArrayEquals(new Object[] {1, 3, 5}, array); + Assert.assertArrayEquals(new Object[] {1, 3, 5}, StackUtil.getTop(stack, 4)); + Assert.assertArrayEquals(new Object[] {1, 3, 5}, array); + } + + /** + * Method: isValidPairs(String s) + */ + @Test + public void testIsValidPairs() throws Exception { +//TODO: Test goes here... + Assert.assertTrue(StackUtil.isValidPairs("{sqrt[p*(p-a)*(p-b)*(p-c)]}")); + Assert.assertFalse(StackUtil.isValidPairs("{sqrt[p*[p-a)*(p-b]*(p-c)]}")); + } + +} diff --git a/group01/895457260/code/src/test/java/datastructure/LinkedListTest.java b/group01/895457260/code/src/test/java/datastructure/LinkedListTest.java index dee34c8b3f..d6437ec636 100644 --- a/group01/895457260/code/src/test/java/datastructure/LinkedListTest.java +++ b/group01/895457260/code/src/test/java/datastructure/LinkedListTest.java @@ -114,7 +114,7 @@ public void testRemoveFirstHalf() throws Exception { /** * - * Method: remove(int i, int length) + * Method: remove(int i, int size) * */ @Test diff --git a/group01/895457260/code/src/test/java/jvm/ClassFileLoaderTest.java b/group01/895457260/code/src/test/java/jvm/ClassFileLoaderTest.java index ac48c1a4d6..23a2341d8f 100644 --- a/group01/895457260/code/src/test/java/jvm/ClassFileLoaderTest.java +++ b/group01/895457260/code/src/test/java/jvm/ClassFileLoaderTest.java @@ -1,22 +1,42 @@ package jvm; +import jvm.classfile.attribute.item.impl.CodeAttr; +import jvm.classfile.ClassFile; +import jvm.classfile.ClassIndex; +import jvm.classfile.ConstantPool; +import jvm.classfile.constant.item.impl.ClassInfo; +import jvm.classfile.constant.item.impl.MethodRefInfo; +import jvm.classfile.constant.item.impl.NameAndTypeInfo; +import jvm.classfile.constant.item.impl.UTF8Info; import jvm.exception.ReadClassException; +import jvm.classfile.field.Field; +import jvm.classfile.method.Method; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import java.util.List; + public class ClassFileLoaderTest { + private static final String FULL_QUALIFIED_CLASS_NAME = "jvm/EmployeeV1"; + private static final String LOAD_CLASS_NAME = "jvm.EmployeeV1"; private static ClassFileLoader loader; private static String path1 = "target/classes"; private static String path2 = "target/test-classes"; + + private static ClassFile clzFile = null; @Before public void setUp() throws Exception { loader = new ClassFileLoader(); loader.addClassPath(path1); loader.addClassPath(path2); + + if (clzFile == null) { + clzFile = loader.load(LOAD_CLASS_NAME); + } } @After @@ -30,20 +50,18 @@ public void testClassPath() { @Test public void testClassFileLength() throws ReadClassException { - String className = "jvm.EmployeeV1"; - byte[] byteCodes = loader.readBinaryCode(className); + byte[] byteCodes = loader.readBinaryCode(LOAD_CLASS_NAME); // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 Assert.assertEquals(1016, byteCodes.length); } @Test public void testMagicNumber() throws ReadClassException { - String className = "jvm.EmployeeV1"; - byte[] byteCodes = loader.readBinaryCode(className); + byte[] byteCodes = loader.readBinaryCode(LOAD_CLASS_NAME); byte[] codes = new byte[] {byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3]}; - - String actualValue = this.byteToHexString(codes); - Assert.assertEquals("cafebabe", actualValue); + + boolean check = loader.checkMagicNumber(codes); + Assert.assertTrue(check); } private String byteToHexString(byte[] codes) { @@ -58,4 +76,166 @@ private String byteToHexString(byte[] codes) { } return buffer.toString(); } + + + + + + @Test + public void testVersion() { + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + } + + @Test + public void testConstantPool() { + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(7); + Assert.assertEquals(44, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(44); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(11); + Assert.assertEquals(48, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(48); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(12); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(13); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(14); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(15); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(16); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(17); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(18); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(1); + Assert.assertEquals(11, methodRef.getClassInfoIndex()); + Assert.assertEquals(36, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(36); + Assert.assertEquals(16, nameAndType.getIndex1()); + Assert.assertEquals(28, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(9); + Assert.assertEquals(7, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(35); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex() { + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + /** + * 下面是第三次JVM课应实现的测试用例 + */ + @Test + public void testReadFields() { + + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + + @Test + public void testMethods() { + + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7012a2bb5022a1cb503b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb502b1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb503b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b204125b606b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb0759128101db7094c2bb60ab1"); + } + } + + private void assertMethodEquals(ConstantPool pool, Method m, + String expectedName, String expectedDesc,String expectedCode) { + String methodName = ((UTF8Info) pool.getConstantInfo(m.getNameIndex())).getValue(); + String methodDesc = ((UTF8Info) pool.getConstantInfo(m.getDescriptorIndex())).getValue(); + String code = ((CodeAttr) m.getAttributes().get(0)).getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } } diff --git a/group01/895457260/code/src/test/java/jvm/EmployeeV1.java b/group01/895457260/code/src/test/java/jvm/EmployeeV1.java index 0ab0e5bd1f..84cdf0d4e6 100644 --- a/group01/895457260/code/src/test/java/jvm/EmployeeV1.java +++ b/group01/895457260/code/src/test/java/jvm/EmployeeV1.java @@ -1,29 +1,28 @@ package jvm; public class EmployeeV1 { - - private String name; + + + private String name; private int age; - + public EmployeeV1(String name, int age) { this.name = name; - this.age = age; - } + this.age = age; + } public void setName(String name) { this.name = name; } - - public void setAge(int age) { - this.age = age; + public void setAge(int age){ + this.age = age; } - - public void sayHello() { - System.out.println("Hello , this is class Employee "); + public void sayHello() { + System.out.println("Hello , this is class Employee "); } - - public static void main(String[] args) { - EmployeeV1 p = new EmployeeV1("Andy", 29); - p.sayHello(); + public static void main(String[] args){ + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + } } \ No newline at end of file diff --git a/group05/1094051862/mini-jvm/.classpath b/group05/1094051862/mini-jvm/.classpath index 9b2ed0d520..e16a825a8f 100644 --- a/group05/1094051862/mini-jvm/.classpath +++ b/group05/1094051862/mini-jvm/.classpath @@ -4,5 +4,7 @@ + + diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java rename to group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/CodeAttr.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..0e0e46f925 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/CodeAttr.java @@ -0,0 +1,96 @@ +package com.coderising.jvm.attr; + +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.loader.ByteCodeIterator; +import com.sun.org.apache.bcel.internal.classfile.Attribute; + + +public class CodeAttr extends AttributeInfo { + private int maxStack ; + private int maxLocals ; + private int codeLen ; + private String code; + public String getCode() { + return code; + } + + //private ByteCodeCommand[] cmds ; + //public ByteCodeCommand[] getCmds() { + // return cmds; + //} + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + //this.cmds = cmds; + } + + public void setLineNumberTable(LineNumberTable t) { + this.lineNumTable = t; + } + + public void setLocalVariableTable(LocalVariableTable t) { + this.localVarTable = t; + } + + public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2toInt(); + int attrLen = iter.nextU4toInt(); + int maxStack = iter.nextU2toInt(); + int maxLocals = iter.nextU2toInt(); + int codeLen = iter.nextU4toInt(); + + String code = iter.nextUxToHexString(codeLen); + System.out.println("code:" + code); + CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, maxLocals, codeLen, code); + + int exceptionTableLen = iter.nextU2toInt(); + if (exceptionTableLen > 0) { + String exTable = iter.nextUxToHexString(exceptionTableLen); + //TODO parse exception_table + System.out.println("exception_table has not been parsed !"); + + } + + int subAttrCount = iter.nextU2toInt(); + System.out.println("subAttrCount:"+subAttrCount); + for (int i = 0; i < subAttrCount; i++) { + int subAttrIndex = iter.nextU2toInt(); + String subAttrName = clzFile.getConstantPool().getUTF8String(subAttrIndex); + System.out.println("subAttrName:" + subAttrName); + + iter.back(2); + + if (AttributeInfo.LINE_NUM_TABLE.equals(subAttrName)) { + LineNumberTable t = LineNumberTable.parse(iter); + codeAttr.setLineNumberTable(t); + + } else if (AttributeInfo.LOCAL_VAR_TABLE.equals(subAttrName)) { + LocalVariableTable t = LocalVariableTable.parse(iter); + codeAttr.setLocalVariableTable(t); + } else if (AttributeInfo.STACK_MAP_TABLE.equals(subAttrName)) { + StackMapTable t = StackMapTable.parse(iter); + codeAttr.setStackMapTable(t); + } else { + throw new RuntimeException("Need to parse " + subAttrName); + } + } + return codeAttr; + } + private void setStackMapTable(StackMapTable t) { + this.stackMapTable = t; + + } + + + + + +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..c6813a07a2 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java @@ -0,0 +1,56 @@ +package com.coderising.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class LineNumberTable extends AttributeInfo { + List items = new ArrayList(); + + private static class LineNumberItem{ + int startPC; + int lineNum; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + public void addLineNumberItem(LineNumberItem item){ + this.items.add(item); + } + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + + } + + public static LineNumberTable parse(ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2toInt(); + int attrLen = iter.nextU4toInt(); + + LineNumberTable t = new LineNumberTable(attrNameIndex, attrLen); + + int linNumTableLen = iter.nextU2toInt(); + + for(int i = 0; i < linNumTableLen; i++) { + LineNumberItem m = new LineNumberItem(); + m.setStartPC(iter.nextU2toInt()); + m.setLineNum(iter.nextU2toInt()); + + t.addLineNumberItem(m); + } + + return t; + } + + + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java rename to group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..1b1233f748 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java @@ -0,0 +1,45 @@ +package com.coderising.jvm.attr; + + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.constant.ConstantPool; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class LocalVariableTable extends AttributeInfo{ + + List items = new ArrayList(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LocalVariableTable parse(ByteCodeIterator iter){ + int index = iter.nextU2toInt(); + int len = iter.nextU4toInt(); + + LocalVariableTable table = new LocalVariableTable(index, len); + + int itemLen = iter.nextU2toInt(); + + for(int i = 0; i < itemLen; i++) { + LocalVariableItem item = new LocalVariableItem(); + item.setStartPC(iter.nextU2toInt()); + item.setLength(iter.nextU2toInt()); + item.setNameIndex(iter.nextU2toInt()); + item.setDescIndex(iter.nextU2toInt()); + item.setIndex(iter.nextU2toInt()); + + table.addLocalVariableItem(item); + } + + return table; + } + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + + +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..caff593698 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java @@ -0,0 +1,30 @@ +package com.coderising.jvm.attr; + + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class StackMapTable extends AttributeInfo{ + + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.nextU2toInt(); + int len = iter.nextU4toInt(); + StackMapTable t = new StackMapTable(index,len); + + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + String code = iter.nextUxToHexString(len); + t.setOriginalCode(code); + + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/clz/AccessFlag.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..cdb8f8859a --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.coderising.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..e38d3091e4 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,94 @@ +package com.coderising.jvm.clz; + +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; +import com.coding.basic.ArrayList; +import com.coding.basic.List; +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + private List fields = new ArrayList(); + private List methods = new ArrayList(); + public void addField(Field f) { + fields.add(f); + } + + public List getFields() { + return fields; + } + + public List getMethods() { + return methods; + } + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + + System.out.println("Super Class Name:"+ getSuperClassName()); + + + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } + + public void addMethod(Method m) { + methods.add(m); + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/clz/ClassIndex.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..df22981441 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package com.coderising.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/ClassInfo.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..92ae6bd6f6 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package com.coderising.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index ;//name_index + public ClassInfo(ConstantPool pool) { + super(pool); + } + public int getUtf8Index() { + return utf8Index; + } + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/ConstantInfo.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..2e3bef0a4e --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/ConstantInfo.java @@ -0,0 +1,30 @@ +package com.coderising.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/ConstantPool.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..0e940b78d0 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/FieldRefInfo.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..7ff9d5fb77 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/MethodRefInfo.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..0feffa65b5 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..dcac7f97c4 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/NullConstantInfo.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..fa90d110fe --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/StringInfo.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..d01065fd53 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index; + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/UTF8Info.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..b7407d146f --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/field/Field.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/field/Field.java new file mode 100644 index 0000000000..d0009dc59c --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/field/Field.java @@ -0,0 +1,54 @@ +package com.coderising.jvm.field; + +import javax.management.RuntimeErrorException; + +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.loader.ByteCodeIterator; + + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + + + private ConstantPool pool; + + public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + + + public static Field parse(ConstantPool pool,ByteCodeIterator iter){ + int accessFlag = iter.nextU2toInt(); + int nameIndex = iter.nextU2toInt(); + int descriptorIndex = iter.nextU2toInt(); + int attributesCount = iter.nextU2toInt(); + System.out.println("Field AttributesCount: "+attributesCount); + + Field f = new Field(accessFlag, nameIndex, descriptorIndex, pool); + + if (attributesCount > 0) { + throw new RuntimeException("Field attributes have not been parsed !"); + } + + return f; + } + + public String toString() { + StringBuffer s = new StringBuffer(); + s.append(pool.getUTF8String(nameIndex)); + s.append(':'); + s.append(pool.getUTF8String(descriptorIndex)); + return s.toString(); + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..69593e37f4 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,56 @@ +package com.coderising.jvm.loader; + +import java.util.Arrays; + +import com.coderising.jvm.util.Util; + +public class ByteCodeIterator { + + byte[] codes; + int pos = 0; + + ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public byte[] getBytes(int len) { + if (pos + len >= codes.length) { + throw new ArrayIndexOutOfBoundsException(); + } + + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos += len; + + return data; + } + + public int nextU1toInt() { + return Util.byteToInt(new byte[] { codes[pos++] }); + } + + public int nextU2toInt() { + return Util.byteToInt(new byte[] { codes[pos++], codes[pos++] }); + } + + public int nextU4toInt() { + return Util.byteToInt(new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] }); + } + + public String nextU4toHexString() { + return Util.byteToHexString(new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] }); + } + + public String nextUxToHexString(int len) { + byte[] tmp = new byte[len]; + + for (int i = 0; i < len; i++) { + tmp[i] = codes[pos++]; + } + return Util.byteToHexString(tmp).toLowerCase(); + + } + + public void back(int n) { + this.pos -= n; + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java index 86f1100e6c..b9c66be7e7 100644 --- a/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -10,13 +10,32 @@ import java.util.ArrayList; import java.util.List; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +import com.coderising.jvm.clz.ClassFile; + + public class ClassFileLoader { private List clzPaths = new ArrayList(); - public byte[] readBinaryCode(String className) throws ClassNotFoundException, IOException { + public byte[] readBinaryCode(String className) { + + className = className.replace('.', File.separatorChar) + ".class"; + + for (String path : this.clzPaths) { + + String clzFileName = path + File.separatorChar +className; + byte[] codes = loadClassFile(clzFileName); + if (codes != null) { + return codes; + } + } + return null; + /* if (clzPaths.size() == 0) { - return new byte[0]; + throw new ClassNotFoundException(className); } String actualPath = getActualPath(className); @@ -46,31 +65,41 @@ public byte[] readBinaryCode(String className) throws ClassNotFoundException, IO } finally { is.close(); bos.close(); - } + } */ } - private String getActualPath(String className) { + private byte[] loadClassFile(String clzFileName) { + File f = new File(clzFileName); + try { + return IOUtils.toByteArray(new FileInputStream(f)); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + /*private String getActualPath(String className) { String fileName = className.substring(className.lastIndexOf(".") + 1) + ".class"; String dirPath = className.substring(0, className.lastIndexOf(".")).replace(".", "\\"); return clzPaths.get(clzPaths.size() - 1) + "\\" + dirPath + "\\" + fileName; //classPath 取最近添加的一个 - } + }*/ public void addClassPath(String path) { - if (path == null) { + if (this.clzPaths.contains(path)) { return; } - clzPaths.add(path); + this.clzPaths.add(path); } public String getClassPath() { - if (clzPaths.size() == 0) { + /*if (clzPaths.size() == 0) { return ""; } @@ -81,8 +110,18 @@ public String getClassPath() { buffer.append(";"); } - return buffer.substring(0, buffer.length() - 1);// 去除最后一个分号 + return buffer.substring(0, buffer.length() - 1);*/// 去除最后一个分号 + return StringUtils.join(clzPaths, ";"); } + + public ClassFile loadClass(String className) { + + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + } diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..09354e7f5f --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java @@ -0,0 +1,153 @@ +package com.coderising.jvm.loader; + +import java.io.UnsupportedEncodingException; + +import com.coderising.jvm.clz.AccessFlag; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.FieldRefInfo; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.NullConstantInfo; +import com.coderising.jvm.constant.StringInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + ClassFile clzFile = new ClassFile(); + ByteCodeIterator iter = new ByteCodeIterator(codes); + + String magicNumber = iter.nextU4toHexString(); + if (!"cafebabe".equals(magicNumber)) { + return null; + } + + clzFile.setMinorVersion(iter.nextU2toInt()); + clzFile.setMajorVersion(iter.nextU2toInt()); + + ConstantPool pool = parseConstantPool(iter); + clzFile.setConstPool(pool); + + clzFile.setAccessFlag(parseAccessFlag(iter)); + clzFile.setClassIndex(parseClassIndex(iter)); + + parseInterfaces(iter);//如果实现接口,需要进一步解析 + + parseFields(clzFile, iter); + + parseMethods(clzFile, iter); + return clzFile; + } + + private void parseMethods(ClassFile clzFile, ByteCodeIterator iter) { + int methodCount = iter.nextU2toInt(); + System.out.println("methodCount:" + methodCount); + for (int i = 0; i < methodCount; i++) { + System.out.println("method :" + (i+1)); + Method m = Method.parse(clzFile, iter); + clzFile.addMethod(m); + } + } + + private void parseFields(ClassFile clzFile, ByteCodeIterator iter) { + int fieldCount = iter.nextU2toInt(); + System.out.println("fieldCount:" + fieldCount); + for (int i = 0; i < fieldCount; i++) { + Field f = Field.parse(clzFile.getConstantPool(), iter); + clzFile.addField(f); + } + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + //int flagValue = iter.nextU2toInt(); + return new AccessFlag(iter.nextU2toInt()); + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(iter.nextU2toInt()); + classIndex.setSuperClassIndex(iter.nextU2toInt()); + + return classIndex; + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + int constantPoolIndexCount = iter.nextU2toInt(); + System.out.println("Constant Pool Index Count:" + constantPoolIndexCount); + ConstantPool pool = new ConstantPool(); + + pool.addConstantInfo(new NullConstantInfo()); + + for (int i = 1; i <= constantPoolIndexCount - 1; i++) { + int tag = iter.nextU1toInt(); + if (tag == 7) {//Class Info + int nameIndex = iter.nextU2toInt(); + ClassInfo clzInfo = new ClassInfo(pool); + clzInfo.setUtf8Index(nameIndex); + + pool.addConstantInfo(clzInfo); + } else if (tag == 1) {//Utf8 Info + int length = iter.nextU2toInt(); + byte[] data = iter.getBytes(length); + String value = null; + try { + value = new String(data, "utf-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + UTF8Info utf8Info = new UTF8Info(pool); + utf8Info.setLength(length); + utf8Info.setValue(value); + + pool.addConstantInfo(utf8Info); + } else if (tag == 8) {// String Info + int strIndex = iter.nextU2toInt(); + StringInfo stringInfo = new StringInfo(pool); + stringInfo.setIndex(strIndex); + + pool.addConstantInfo(stringInfo); + } else if (tag == 9) {// Fieldref Info + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + fieldRefInfo.setClassInfoIndex(iter.nextU2toInt()); + fieldRefInfo.setNameAndTypeIndex(iter.nextU2toInt()); + + pool.addConstantInfo(fieldRefInfo); + } else if (tag == 10) {// Methodref Info + int classIndex = iter.nextU2toInt(); + int nameAndTypeIndex = iter.nextU2toInt(); + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + methodRefInfo.setClassInfoIndex(classIndex); + methodRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + + pool.addConstantInfo(methodRefInfo); + } else if (tag == 12) { //NameAndType Info + int nameIndex = iter.nextU2toInt(); + int descriptorIndex = iter.nextU2toInt(); + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + nameAndTypeInfo.setIndex1(nameIndex); + nameAndTypeInfo.setIndex2(descriptorIndex); + + pool.addConstantInfo(nameAndTypeInfo); + } + else { + throw new RuntimeException("The constant pool has not realized at tag=" + tag); + } + } + return pool; + } + + private void parseInterfaces(ByteCodeIterator iter) { + int interfaceCount = iter.nextU2toInt(); + + System.out.println("interfaceCount:" + interfaceCount); + + // TODO : 如果实现了interface, 这里需要解析 + } + + +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/method/Method.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/method/Method.java new file mode 100644 index 0000000000..13a8e41994 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/method/Method.java @@ -0,0 +1,80 @@ +package com.coderising.jvm.method; + +import com.coderising.jvm.clz.ClassFile; + +import javax.management.RuntimeErrorException; + +import com.coderising.jvm.attr.AttributeInfo; +import com.coderising.jvm.attr.CodeAttr; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.loader.ByteCodeIterator; + + + +public class Method { + + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + + private ClassFile clzFile; + + + public ClassFile getClzFile() { + return clzFile; + } + + public int getNameIndex() { + return nameIndex; + } + public int getDescriptorIndex() { + return descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr code) { + this.codeAttr = code; + } + + public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) { + this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ + int accessFlag = iter.nextU2toInt(); + int nameIndex = iter.nextU2toInt(); + int descriptorIndex = iter.nextU2toInt(); + int attributesCount = iter.nextU2toInt(); + + System.out.println("Method AttributesCount:"+ attributesCount); + + Method m = new Method(clzFile, accessFlag, nameIndex, descriptorIndex); + + for (int i = 0; i < attributesCount; i++) { + int attrNameIndex = iter.nextU2toInt(); + iter.back(2); //解析attrNameIndex就是下面一个属性的一部分,所以下面要解析属性,指针应该回退。 + String attrName = clzFile.getConstantPool().getUTF8String(attrNameIndex); + System.out.println("attrName:"+attrName); + if (AttributeInfo.CODE.equals(attrName)) { + CodeAttr codeAttr = CodeAttr.parse(clzFile, iter); + m.setCodeAttr(codeAttr); + } else { + throw new RuntimeException("The attribute '"+ attrName +"' has not been implemented, " + + "the only implemented attribute is Code attribute !"); + } + + } + return m; + + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java index b15eb7e99d..db02c29132 100644 --- a/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -7,7 +7,17 @@ import org.junit.Before; import org.junit.Test; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.field.Field; import com.coderising.jvm.loader.ClassFileLoader; +import com.coderising.jvm.method.Method; +import com.coding.basic.List; @@ -15,11 +25,20 @@ public class ClassFileloaderTest { + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; static String path1 = "E:\\practise\\group05\\1094051862\\mini-jvm\\bin"; static String path2 = "C:\\temp"; - + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + + clzFile = loader.loadClass(className); + clzFile.print(); + } @Before public void setUp() throws Exception { @@ -60,7 +79,6 @@ public void testClassFileLength() throws ClassNotFoundException, IOException { @Test public void testMagicNumber() throws ClassNotFoundException, IOException{ - ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path1); String className = "com.coderising.jvm.test.EmployeeV1"; @@ -91,5 +109,169 @@ private String byteToHexString(byte[] codes ){ } return buffer.toString(); } + + /** + * ---------------------------------------------------------------------- + */ + + + @Test + public void testVersion(){ + + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool(){ + + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + /** + * 下面是第三次JVM课应实现的测试用例 + */ + @Test + public void testReadFields(){ + + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = (Field) fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = (Field) fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + @Test + public void testMethods(){ + + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = (Method) methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + + } + { + Method m = (Method) methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + + } + { + Method m = (Method) methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = (Method) methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + + } + { + Method m = (Method) methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } } diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/util/Util.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/util/Util.java new file mode 100644 index 0000000000..176f70d002 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/util/Util.java @@ -0,0 +1,24 @@ +package com.coderising.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes){ + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i implements List { + + private int size = 0; + + private Object[] elementData = new Object[10]; + + private int increaseSize = 10; + private void increaseArray() { + Object[] newData = Arrays.copyOf(elementData, elementData.length + increaseSize); + elementData = newData; + } + public void add(T o){ + if (size == elementData.length) { + increaseArray(); + elementData[size++] = o; + } else { + elementData[size++] = o; + } + } + public void add(int index, T o){ + if (index < 0 || index > size) { + System.out.println("错误提示:index > size || index < 0"); + return; + } + T temp; + for (int i = index; i < size; i++) { + temp = (T) elementData[i]; + elementData[i] = o; + o = temp; + } + elementData[size ++] = o; + } + + public T get(int index){ + if (index < 0 || index > size ){ + return null; + } + return (T) elementData[index]; + } + + public T remove(int index){ + if (index < 0 || index > size ){ + return null; + } + Object result = elementData[index]; + for (int i = index; i < size-1; i++) { + elementData[i] = elementData[i + 1]; + } + elementData[size-1] = null; + size --; + return (T) result; + } + + public int size(){ + return size; + } + + public Iterator iterator(){ + return new Iterator() { + private int cusor = 0; + @Override + public Object next() { + if (!hasNext()) { + System.out.println("next: !hasNext"); + return null; + } + return elementData[cusor ++]; + } + @Override + public boolean hasNext() { + return cusor < size; + } + }; + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/ArrayListTest.java b/group05/1094051862/mini-jvm/src/com/coding/basic/ArrayListTest.java new file mode 100644 index 0000000000..c733e4e7a9 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/ArrayListTest.java @@ -0,0 +1,31 @@ +package com.coding.basic; + +import org.junit.Assert; +import org.junit.Test; + +public class ArrayListTest { + + @Test + public void test() { + List list = new ArrayList(); + for(int i = 0; i < 10; i++) { + list.add(i); + } + Assert.assertEquals(10, list.size()); + list.add(11); + list.add(3,99); + Assert.assertEquals(99, list.get(3)); + Assert.assertEquals(12, list.size()); + Assert.assertEquals(99, list.remove(3)); + Assert.assertEquals(11, list.size()); + Iterator iterator = list.iterator(); + for (int i = 0; i< list.size(); i++) { + System.out.println(list.get(i)); + } + System.out.println("======"); + while (iterator.hasNext()) { + System.out.println(iterator.next()); + } + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/BinaryTreeNode.java b/group05/1094051862/mini-jvm/src/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..266eff3d56 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/BinaryTreeNode.java @@ -0,0 +1,32 @@ +package com.coding.basic; + +public class BinaryTreeNode { + + private Object data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public Object getData() { + return data; + } + public void setData(Object data) { + this.data = data; + } + public BinaryTreeNode getLeft() { + return left; + } + public void setLeft(BinaryTreeNode left) { + this.left = left; + } + public BinaryTreeNode getRight() { + return right; + } + public void setRight(BinaryTreeNode right) { + this.right = right; + } + + public BinaryTreeNode insert(Object o){ + return null; + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/Iterator.java b/group05/1094051862/mini-jvm/src/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..dbe8b9afb2 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/Iterator.java @@ -0,0 +1,7 @@ +package com.coding.basic; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/LinkedList.java b/group05/1094051862/mini-jvm/src/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..e05587dd02 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/LinkedList.java @@ -0,0 +1,334 @@ +package com.coding.basic; + +import java.util.Arrays; + +public class LinkedList implements List { + + private Node head; + private Node last; + private int size = 0; + + public void add(Object o) { + if (head == null) { + head = new Node(o, null); + size++; + return; + } + Node n = new Node(o, null); + if (last == null) { + last = n; + head.next = last; + } + last.next = n; + last = n; + size++; + } + + public void add(int index, Object o) { + if (index < 0 || index > size) { + System.out.println("linkedList.add: index < 0 || index > size"); + return; + } + if (index == size) { + add(o); + return; + } + if (index == 0) { + addFirst(o); + return; + } + Node pre = head; + for (int i = 1; i < index; i++) { + pre = pre.next; + } + Node post = pre.next; + Node n = new Node(o, post); + pre.next = n; + size++; + } + + public Object get(int index) { + return this.getNode(index).data; + } + + public Node getNode(int index) { + if (index == 0) { + return this.head; + } + Node n = head; + for (int i = 1; i <= index; i++) { + n = n.next; + } + return n; + } + + public Object remove(int index) { + if (index < 0 || index >= size) { + System.out.println("remove :index < 0 || index >= size"); + return null; + } + if (index == 0) { + return removeFirst(); + } + if (index == size - 1) { + return removeLast(); + } + Node pre = head; + for (int i = 1; i < index; i++) { + pre = pre.next; + } + Node n = pre.next; + Node post = n.next; + n.next = null; + pre.next = post; + size--; + return n.data; + } + + public int size() { + return size; + } + + public void addFirst(Object o) { + Node n = new Node(o, head); + head = n; + size++; + return; + } + + public void addLast(Object o) { + Node n = new Node(o, null); + last.next = n; + last = n; + size++; + return; + } + + public Object removeFirst() { + Object o = head.data; + Node n = head.next; + head.next = null; + head = n; + size--; + return o; + } + + public Object removeLast() { + Node preLast = head; + for (int i = 1; i < size; i++) { + preLast = preLast.next; + } + preLast.next = null; + Object o = last.data; + last = preLast; + size--; + return o; + } + + public Iterator iterator() { + return new Iterator() { + int cusor = 0; + Node current = head; + + @Override + public Object next() { + if (!hasNext()) { + System.out.println("next : !hasNext"); + return null; + } + Object o = current.data; + current = current.next; + cusor++; + return o; + } + + @Override + public boolean hasNext() { + return cusor < size; + } + }; + } + + private static class Node { + + Object data; + Node next; + + public Node(Object data, Node next) { + this.data = data; + this.next = next; + } + } + + /** + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + if (this.size() < 2) { + return; + } + for (int i = this.size() - 1; i > 0; i--) { + this.getNode(i).next = this.getNode(i - 1); + } + Node temp = this.last; + this.last = this.head; + this.head = temp; + } + + /** + * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 + * ,删除以后的值为7,8,10 + */ + public void removeFirstHalf() { + + int delSize = this.size() >> 1; + + Node temp = this.getNode(delSize);// getNode(index) + // 方法依赖前面元素的next指针,所以此语句在for循环前面 + + for (int i = delSize - 1; i >= 0; i--) { + this.getNode(i).next = null; + this.size--; + } + + this.head = temp;// 由于getNode(index) 方法如果index传入0 + // ,返回head,所以此语句要方法for循环后面 + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + if (i < 0 || length < 0 || this.size() < i + length) { + return; + } + if (i == 0 && this.size() == length) { + this.head = null; + this.size = 0; + this.last = null; + return; + } + Node iNode = this.getNode(i - 1); + Node pre = this.getNode(i + length - 1); + Node post = this.getNode(i + length); + pre.next = null; + iNode.next = post; + this.size = this.size() - length; + } + + /** + * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 例如当前链表 = + * 11->101->201->301->401->501->601->701 listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * + * @param list + */ + public int[] getElements(LinkedList list) { + Iterator select = list.iterator(); + Iterator original = this.iterator(); + int[] result = new int[this.size()]; + int cosur = 0; + while (select.hasNext()) { + int s = (int) select.next(); + String selStr = String.valueOf(s); + while (original.hasNext()) { + int o = (int) original.next(); + String oriStr = String.valueOf(o); + if (oriStr.contains(selStr)) { + result[0] = o; + cosur++; + break; + } + } + } + return Arrays.copyOf(result, cosur - 1); + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 + * + * @param list + */ + + public void subtract(LinkedList list) { + Iterator select = list.iterator(); + Iterator original = this.iterator(); + int[] result = new int[this.size()]; + int cosur = 0; + while (select.hasNext()) { + int sel = (int) select.next(); + + while (original.hasNext()) { + int ori = (int) original.next(); + cosur++; + if (ori == sel) { + remove(cosur); + } + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + if (this.size() == 0) { + return; + } + for (int i = this.size(); i > 0; i--) { + if ((int) get(i) == (int) get(i - 1)) { + this.remove(i); + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + public void removeRange(int min, int max) { + int minIndex = 0; + int maxIndex = 0; + for (int i = this.size(); i > 0; i--) { + if (max > (int) get(i)) { + maxIndex = i; + } + } + for (int i = 0; i < maxIndex; i++) { + if (min < (int) get(i)) { + minIndex = i; + } + } + remove(minIndex, maxIndex - minIndex); + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * + * @param list + */ + public LinkedList intersection(LinkedList list) { + LinkedList result = new LinkedList(); + Iterator select = list.iterator(); + Iterator original = this.iterator(); + + int sel = (int) select.next(); + int ori = (int) original.next(); + while (original.hasNext() && select.hasNext()) { + if (ori == sel) { + result.add(ori); + } else if (ori < sel) { + ori = (int) original.next(); + } else { + sel = (int) select.next(); + } + } + return result; + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/LinkedListTest.java b/group05/1094051862/mini-jvm/src/com/coding/basic/LinkedListTest.java new file mode 100644 index 0000000000..db55063435 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/LinkedListTest.java @@ -0,0 +1,79 @@ +package com.coding.basic; + +import junit.framework.Assert; + +import org.junit.Test; + +public class LinkedListTest extends LinkedList { + + @Test + public void test() { + List list = new LinkedList(); + list.add(0); + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + list.add(3, 33); + list.add(0, 100); + list.add(8,800); + Assert.assertEquals(9, list.size()); + Assert.assertEquals(100, list.get(0)); + Assert.assertEquals(0, list.get(1)); + Assert.assertEquals(1, list.get(2)); + Assert.assertEquals(2, list.get(3)); + Assert.assertEquals(33, list.get(4)); + Assert.assertEquals(3, list.get(5)); + Assert.assertEquals(4, list.get(6)); + Assert.assertEquals(800, list.get(8)); + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + System.out.println(iterator.next()); + } + } + @Test + public void testReverse() { + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + list.add(6); + list.add(7); + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + System.out.print(iterator.next()); + } + System.out.println(); + list.reverse(); + Iterator iterator2 = list.iterator(); + while (iterator2.hasNext()) { + System.out.print(iterator2.next()); + } + System.out.println(); + list.removeFirstHalf(); + Iterator iterator3 = list.iterator(); + while (iterator3.hasNext()) { + System.out.print(iterator3.next()); + } + System.out.println(); + + } + @Test + public void testRemove() { + LinkedList list = new LinkedList(); + int i = 0; + while( i < 20) { + list.add(i); + i ++; + } + list.remove(3, 10); + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + System.out.print(iterator.next()); + } + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/List.java b/group05/1094051862/mini-jvm/src/com/coding/basic/List.java new file mode 100644 index 0000000000..c52c1aef0e --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/List.java @@ -0,0 +1,10 @@ +package com.coding.basic; + +public interface List { + public void add(T t); + public void add(int index, T t); + public Object get(int index); + public Object remove(int index); + public int size(); + public Iterator iterator(); +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/Queue.java b/group05/1094051862/mini-jvm/src/com/coding/basic/Queue.java new file mode 100644 index 0000000000..e16a80b13c --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/Queue.java @@ -0,0 +1,25 @@ +package com.coding.basic; + +public class Queue { + private List list = new ArrayList(); + private int size = 0; + public void enQueue(Object o){ + list.add(o); + size ++; + } + + public Object deQueue(){ + if (size == 0) + return null; + size --; + return list.remove(0); + } + + public boolean isEmpty(){ + return size == 0; + } + + public int size(){ + return size; + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/QueueTest.java b/group05/1094051862/mini-jvm/src/com/coding/basic/QueueTest.java new file mode 100644 index 0000000000..1feee8dde1 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/QueueTest.java @@ -0,0 +1,24 @@ +package com.coding.basic; + +import static org.junit.Assert.*; +import junit.framework.Assert; + +import org.junit.Test; + +public class QueueTest { + + @Test + public void test() { + Queue queue = new Queue(); + for (int i = 0; i < 100; i++) { + queue.enQueue(i); + } + Assert.assertEquals(100, queue.size()); + for (int i = 0; i < 100; i++) { + Assert.assertEquals(i, queue.deQueue()); + } + Assert.assertEquals(0, queue.size()); + + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/Stack.java b/group05/1094051862/mini-jvm/src/com/coding/basic/Stack.java new file mode 100644 index 0000000000..57eae3d31d --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/Stack.java @@ -0,0 +1,28 @@ +package com.coding.basic; + +public class Stack { + private List elementData = new ArrayList(); + private int size = 0; + public void push(Object o){ + elementData.add(o); + size ++; + } + + public Object pop(){ + if (size == 0) + return null; + return elementData.remove(--size); + } + + public Object peek(){ + if (size == 0) + return null; + return elementData.get(size - 1); + } + public boolean isEmpty(){ + return size == 0; + } + public int size(){ + return size; + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/StackTest.java b/group05/1094051862/mini-jvm/src/com/coding/basic/StackTest.java new file mode 100644 index 0000000000..e3eabe44a1 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/StackTest.java @@ -0,0 +1,26 @@ +package com.coding.basic; + +import static org.junit.Assert.*; +import junit.framework.Assert; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class StackTest { + + @Test + public void test() { + Stack stack = new Stack(); + for (int i = 0; i < 100; i++) { + stack.push(i); + } + Assert.assertEquals(100, stack.size()); + Assert.assertEquals(99, stack.pop()); + for (int i = 98; i >= 0; i--) { + Assert.assertEquals(i, stack.peek()); + Assert.assertEquals(i, stack.pop()); + } + Assert.assertEquals(0, stack.size()); + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/stack/Stack.java b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/Stack.java new file mode 100644 index 0000000000..5abd9499d5 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/Stack.java @@ -0,0 +1,42 @@ +package com.coding.basic.stack; + +import com.coding.basic.ArrayList; +import com.coding.basic.List; + +public class Stack { + private List elementData = new ArrayList(); + private int size = 0; + public void push(Object o){ + elementData.add(o); + size ++; + } + + public Object pop(){ + if (size == 0) + return null; + return elementData.remove(--size); + } + + public Object peek(){ + if (size == 0) + return null; + return elementData.get(size - 1); + } + public boolean isEmpty(){ + return size == 0; + } + public int size(){ + return size; + } + public String toString() { + StringBuffer join = new StringBuffer("["); + for(int i = 0; i < size; i++) { + join.append(elementData.get(i)); + if (i != size - 1) { + join.append(","); + } + } + join.append("]"); + return join.toString(); + } +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/stack/StackUtil.java b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/StackUtil.java new file mode 100644 index 0000000000..cdb09886fa --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/StackUtil.java @@ -0,0 +1,108 @@ +package com.coding.basic.stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if (s == null || s.size() == 0) { + return; + } + Stack s1 = new Stack(); + Stack s2 = new Stack(); + + reverseTo(s, s1); + reverseTo(s1, s2); + reverseTo(s2, s); + } + + private static void reverseTo(Stack s, Stack s1) { + while(!s.isEmpty()) { + s1.push(s.pop()); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if (o == null || s == null || s.size() == 0) { + return; + } + Stack temp = new Stack(); + reverseTo(s,temp); + while(!temp.isEmpty()) { + if (temp.peek().equals(o)) { + temp.pop(); + continue; + } + s.push(temp.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if (len <= 0 || s == null || s.size() < len) { + return null; + } + Object[] objs = new Object[len]; + for(int i = 0; i < len; i++) { + objs[i] = s.pop(); + } + for(int i = len-1; i >= 0; i--) { + s.push(objs[i]); + } + return objs; + } + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + char[] c = s.toCharArray(); + Stack tag = new Stack(); + for (int i = 0; i < c.length; i++) { + switch(c[i]) { + case '(': + case '[': + case '{': + tag.push(c[i]); + break; + case ')': + if (tag.isEmpty() || '(' != (char)tag.pop()) { + return false; + } + break; + case '}': + if (tag.isEmpty() || '{' != (char)tag.pop()) { + return false; + } + break; + case ']': + if (tag.isEmpty() || '[' != (char)tag.pop()) { + return false; + } + break; + } + } + if (!tag.isEmpty()) { + return false; + } + return true; + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/stack/StackUtilTest.java b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..31c0d72dc1 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/StackUtilTest.java @@ -0,0 +1,61 @@ +package com.coding.basic.stack; + +import static org.junit.Assert.*; + +import org.apache.commons.lang3.ArrayUtils; +import org.junit.Assert; +import org.junit.Test; + +public class StackUtilTest { + + @Test + public void testReverse() { + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + stack.push(5); + System.out.println(stack.toString()); + StackUtil.reverse(stack); + System.out.println(stack.toString()); + } + + @Test + public void testRemove() { + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + stack.push(5); + System.out.println(stack.toString()); + StackUtil.remove(stack, 5); + System.out.println(stack.toString()); + StackUtil.remove(stack, 2); + System.out.println(stack.toString()); + } + + @Test + public void testGetTop() { + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + stack.push(5); + System.out.println(stack.toString()); + Object[] top = StackUtil.getTop(stack, 3); + System.out.println(ArrayUtils.toString(top, null)); + System.out.println(stack.toString()); + } + + @Test + public void testIsValidPairs() { + String str = "sdf{sdf[sdf]sdfsdff}"; + String str2 = "[sdf(sdf{sdf]}sdf)"; + Assert.assertTrue(StackUtil.isValidPairs(str)); + Assert.assertTrue(!StackUtil.isValidPairs(str2)); + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/InfixExpr.java b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/InfixExpr.java new file mode 100644 index 0000000000..dc51c6adf3 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/InfixExpr.java @@ -0,0 +1,74 @@ +package com.coding.basic.stack.expr; + +import java.util.List; + +import com.coding.basic.stack.Stack; +import com.coding.basic.stack.StackUtil; + +public class InfixExpr { + String expr = null; + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + + TokenParser parser = new TokenParser(); + List tokens = parser.parse(expr); + + Stack opStack = new Stack(); + Stack numStack = new Stack(); + + for (Token t : tokens) { + if (t.isOperator()) { + if (opStack.isEmpty()) { + opStack.push(t); + } else { + Token topOperator = (Token) opStack.peek(); + if (t.comparePriority(topOperator) >= 0) { + opStack.push(t); + } else { + Float f1 = (Float) numStack.pop(); + Float f2 = (Float) numStack.pop(); + numStack.push(calculate(topOperator.getValue(), f2, f1)); + opStack.pop(); + opStack.push(t); + } + } + } else if (t.isDigit()) { + numStack.push(Float.valueOf(t.getValue())); + } + } + /*StackUtil.reverse(numStack); + StackUtil.reverse(opStack);*/ + while (!opStack.isEmpty()) { + Float f1 = (Float) numStack.pop(); + Float f2 = (Float) numStack.pop(); + Token opr = (Token) opStack.pop(); + numStack.push(calculate(opr.getValue(), f2, f1)); + } + return (Float) numStack.pop(); + //return 0.0f; + } + + private Float calculate(String op, Float f1, Float f2) { + System.out.println(f1 + "=====" +f2); + switch (op) { + case "*": + System.out.println(" * "); + return f1 * f2; + case "/": + System.out.println("/"); + return f1 / f2; + case "+": + System.out.println("+"); + return f1 + f2; + case "-": + System.out.println("-"); + return f1 - f2; + } + return 0.0f; + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/InfixExprTest.java b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/InfixExprTest.java new file mode 100644 index 0000000000..a6c3d24012 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/InfixExprTest.java @@ -0,0 +1,54 @@ +package com.coding.basic.stack.expr; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class InfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + //InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); + { + InfixExpr expr = new InfixExpr("2+3*4+5"); + Assert.assertEquals(19.0, expr.evaluate(), 0.001f); + } + { + InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); + Assert.assertEquals(100.0, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("3*20/2"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("20/2*3"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("10-30+50"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + } + @Test + public void test0001() { + InfixExpr expr = new InfixExpr("2+3*4+5"); + String s = "23+3*4+5"; + new TokenParser().parse(s); + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/Token.java b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/Token.java new file mode 100644 index 0000000000..b8abf39546 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/Token.java @@ -0,0 +1,61 @@ +package com.coding.basic.stack.expr; + +public class Token { + + public static final int OPRATOR = 0; + public static final int NUMBER = 1; + + private int signal; + private String value; + + public Token(int signal, String digit) { + this.signal = signal; + this.value = digit; + } + + public boolean isOperator() { + return this.signal == Token.OPRATOR; + } + + public boolean isDigit() { + return this.signal == Token.NUMBER; + } + + public int getSignal() { + return signal; + } + + public void setSignal(int signal) { + this.signal = signal; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public int comparePriority(Token topOperator) { + int topOptrPriority = 0; + int optPriority = 0; + if (topOperator.getValue().indexOf('*')>=0 || topOperator.getValue().indexOf('/')>=0) { + topOptrPriority = 1; + } + if (topOperator.getValue().indexOf('+')>=0 || topOperator.getValue().indexOf('-')>=0) { + topOptrPriority = 0; + } + if (this.getValue().indexOf('+')>=0 || this.getValue().indexOf('-')>=0) { + optPriority = 0; + } + if (this.getValue().indexOf('*')>=0 || this.getValue().indexOf('/')>=0) { + optPriority = 1; + } + + + return optPriority - topOptrPriority; + } + + +} diff --git a/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/TokenParser.java b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/TokenParser.java new file mode 100644 index 0000000000..447894d7f4 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coding/basic/stack/expr/TokenParser.java @@ -0,0 +1,52 @@ +package com.coding.basic.stack.expr; + +import java.util.ArrayList; +import java.util.List; + + + +public class TokenParser { + + public List parse(String expr) { + + List tokens = new ArrayList(); + int i = 0; + while (i < expr.length()) { + char c = expr.charAt(i); + if (charIsOperator(c)) { + Token t = new Token(Token.OPRATOR, String.valueOf(c)); + tokens.add(t); + i ++; + } else if (charIsDigit(c)) { + int nextOperatorIndex = indexOfNextOperator(i,expr); + String value = expr.substring(i, nextOperatorIndex); + Token t = new Token(Token.NUMBER, value); + tokens.add(t); + i = nextOperatorIndex; + } + System.out.println(c); + } + + return tokens; + } + + private int indexOfNextOperator(int nowIndex, String expr) { + for (int i = nowIndex; i < expr.length(); i++) { + char c = expr.charAt(i); + if (charIsOperator(c)) { + return i; + } + } + return expr.length();//如果后面没有操作符,返回字符串长度,用于截取数字 + } + + private boolean charIsDigit(char c) { + return c>='0' && c<='9'; + } + + private boolean charIsOperator(char c) { + + return c=='+' || c=='-' || c=='*' || c=='/'; + } + +} diff --git a/group05/1094051862/test01/.classpath b/group05/1094051862/test01/.classpath index 6f95a0c3bd..2ffae0aee1 100644 --- a/group05/1094051862/test01/.classpath +++ b/group05/1094051862/test01/.classpath @@ -4,5 +4,6 @@ + diff --git a/group05/1094051862/test01/src/com/coding/basic/stack/Stack.java b/group05/1094051862/test01/src/com/coding/basic/stack/Stack.java new file mode 100644 index 0000000000..dd23c0c422 --- /dev/null +++ b/group05/1094051862/test01/src/com/coding/basic/stack/Stack.java @@ -0,0 +1,42 @@ +package com.coding.basic.stack; + +import com.coding.basic.ArrayList; +import com.coding.basic.List; + +public class Stack { + private List elementData = new ArrayList(); + private int size = 0; + public void push(Object o){ + elementData.add(o); + size ++; + } + + public Object pop(){ + if (size == 0) + return null; + return elementData.remove(--size); + } + + public Object peek(){ + if (size == 0) + return null; + return elementData.get(size - 1); + } + public boolean isEmpty(){ + return size == 0; + } + public int size(){ + return size; + } + public String toString() { + StringBuffer join = new StringBuffer("["); + for(int i = 0; i < size; i++) { + join.append(elementData.get(i)); + if (i != size - 1) { + join.append(","); + } + } + join.append("]"); + return join.toString(); + } +} diff --git a/group05/1094051862/test01/src/com/coding/basic/stack/StackUtil.java b/group05/1094051862/test01/src/com/coding/basic/stack/StackUtil.java new file mode 100644 index 0000000000..cdb09886fa --- /dev/null +++ b/group05/1094051862/test01/src/com/coding/basic/stack/StackUtil.java @@ -0,0 +1,108 @@ +package com.coding.basic.stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if (s == null || s.size() == 0) { + return; + } + Stack s1 = new Stack(); + Stack s2 = new Stack(); + + reverseTo(s, s1); + reverseTo(s1, s2); + reverseTo(s2, s); + } + + private static void reverseTo(Stack s, Stack s1) { + while(!s.isEmpty()) { + s1.push(s.pop()); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if (o == null || s == null || s.size() == 0) { + return; + } + Stack temp = new Stack(); + reverseTo(s,temp); + while(!temp.isEmpty()) { + if (temp.peek().equals(o)) { + temp.pop(); + continue; + } + s.push(temp.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if (len <= 0 || s == null || s.size() < len) { + return null; + } + Object[] objs = new Object[len]; + for(int i = 0; i < len; i++) { + objs[i] = s.pop(); + } + for(int i = len-1; i >= 0; i--) { + s.push(objs[i]); + } + return objs; + } + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + char[] c = s.toCharArray(); + Stack tag = new Stack(); + for (int i = 0; i < c.length; i++) { + switch(c[i]) { + case '(': + case '[': + case '{': + tag.push(c[i]); + break; + case ')': + if (tag.isEmpty() || '(' != (char)tag.pop()) { + return false; + } + break; + case '}': + if (tag.isEmpty() || '{' != (char)tag.pop()) { + return false; + } + break; + case ']': + if (tag.isEmpty() || '[' != (char)tag.pop()) { + return false; + } + break; + } + } + if (!tag.isEmpty()) { + return false; + } + return true; + } + +} diff --git a/group05/1094051862/test01/src/com/coding/basic/stack/StackUtilTest.java b/group05/1094051862/test01/src/com/coding/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..31c0d72dc1 --- /dev/null +++ b/group05/1094051862/test01/src/com/coding/basic/stack/StackUtilTest.java @@ -0,0 +1,61 @@ +package com.coding.basic.stack; + +import static org.junit.Assert.*; + +import org.apache.commons.lang3.ArrayUtils; +import org.junit.Assert; +import org.junit.Test; + +public class StackUtilTest { + + @Test + public void testReverse() { + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + stack.push(5); + System.out.println(stack.toString()); + StackUtil.reverse(stack); + System.out.println(stack.toString()); + } + + @Test + public void testRemove() { + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + stack.push(5); + System.out.println(stack.toString()); + StackUtil.remove(stack, 5); + System.out.println(stack.toString()); + StackUtil.remove(stack, 2); + System.out.println(stack.toString()); + } + + @Test + public void testGetTop() { + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + stack.push(5); + System.out.println(stack.toString()); + Object[] top = StackUtil.getTop(stack, 3); + System.out.println(ArrayUtils.toString(top, null)); + System.out.println(stack.toString()); + } + + @Test + public void testIsValidPairs() { + String str = "sdf{sdf[sdf]sdfsdff}"; + String str2 = "[sdf(sdf{sdf]}sdf)"; + Assert.assertTrue(StackUtil.isValidPairs(str)); + Assert.assertTrue(!StackUtil.isValidPairs(str2)); + } + +} diff --git a/group05/284422826/src/com/coderising/jvm/loader/ClassFileLoader.java b/group05/284422826/src/com/coderising/jvm/loader/ClassFileLoader.java deleted file mode 100644 index a15237f0cb..0000000000 --- a/group05/284422826/src/com/coderising/jvm/loader/ClassFileLoader.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.coderising.jvm.loader; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - - -public class ClassFileLoader { - - private List clzPaths = new ArrayList<>(); - - public byte[] readBinaryCode(String className) { - String name = this.getClassPath() + File.separatorChar + className.replace('.', File.separatorChar) + ".class"; - File file = new File(name); - byte[] bytes = new byte[(int)file.length()]; - try { - BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); - while (bis.read(bytes) != -1) { - System.out.println(Arrays.toString(bytes)); - } - } catch (IOException e) { - e.printStackTrace(); - } - return bytes; - } - - - public void addClassPath(String path) { - clzPaths.add(path); - } - - - public String getClassPath() { - StringBuilder path = new StringBuilder(); - for (String str : clzPaths) { - path.append(str).append(";"); - } - return path.substring(0, path.length() - 1); - } - - -} diff --git a/group05/284422826/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group05/284422826/src/com/coderising/jvm/test/ClassFileloaderTest.java deleted file mode 100644 index ca669de57a..0000000000 --- a/group05/284422826/src/com/coderising/jvm/test/ClassFileloaderTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.coderising.jvm.test; - -import com.coderising.jvm.loader.ClassFileLoader; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class ClassFileloaderTest { - static String path1 = "D:\\git\\coding2017\\group05\\284422826\\bin"; - static String path2 = "C:\\temp"; - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testClassPath(){ - - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - loader.addClassPath(path2); - - String clzPath = loader.getClassPath(); - - Assert.assertEquals(path1+";"+path2,clzPath); - - } - - @Test - public void testClassFileLength() { - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - - String className = "com.coderising.jvm.test.EmployeeV1"; - - byte[] byteCodes = loader.readBinaryCode(className); - - // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 - Assert.assertEquals(1056, byteCodes.length); - - } - - @Test - public void testMagicNumber(){ - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - String className = "com.coderising.jvm.test.EmployeeV1"; - byte[] byteCodes = loader.readBinaryCode(className); - byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; - - String acctualValue = this.byteToHexString(codes); - - Assert.assertEquals("cafebabe", acctualValue); - } - - private String byteToHexString(byte[] codes ){ - StringBuilder buffer = new StringBuilder(); - for (byte b : codes) { - int value = b & 0xFF; - String strHex = Integer.toHexString(value); - if (strHex.length() < 2) { - strHex = "0" + strHex; - } - buffer.append(strHex); - } - return buffer.toString(); - } - -} diff --git a/group05/284422826/src/com/coderising/litestruts/struts.xml b/group05/284422826/src/com/coderising/litestruts/struts.xml deleted file mode 100644 index a7cb57e188..0000000000 --- a/group05/284422826/src/com/coderising/litestruts/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - \ No newline at end of file diff --git a/group05/284422826/src/com/coding2017/basic/Iterator.java b/group05/284422826/src/com/coding2017/basic/Iterator.java deleted file mode 100644 index 19e214cfbb..0000000000 --- a/group05/284422826/src/com/coding2017/basic/Iterator.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.coding2017.basic; - -public interface Iterator { - public boolean hasNext(); - public Object next(); - -} diff --git a/group05/284422826/src/com/coding2017/basic/List.java b/group05/284422826/src/com/coding2017/basic/List.java deleted file mode 100644 index 25c197cc18..0000000000 --- a/group05/284422826/src/com/coding2017/basic/List.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.coding2017.basic; - -public interface List { - public void add(Object o); - public void add(int index, Object o); - public Object get(int index); - public Object remove(int index); - public int size(); -} diff --git a/group05/284422826/src/com/coding2017/basic/array/ArrayList.java b/group05/284422826/src/com/coding2017/basic/array/ArrayList.java deleted file mode 100644 index 3baaf4e597..0000000000 --- a/group05/284422826/src/com/coding2017/basic/array/ArrayList.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.coding2017.basic; - -/** - * 功能:实现ArrayList. - * @author zhanglifeng. - */ -public class ArrayList implements List { - private int size = 0; //当前数组大小 - - private Object[] elementData = new Object[5]; //初始数组 - - /** - * 将对象o添加到ArrayList中. - * @param o:需要添加的对象. - */ - public void add(Object o) { - ensureCapacity(size + 1); //确保数组的容量可以装的下size + 1个元素,如果不够则扩容 - - elementData[size] = o; //将o添加到数组中 - size++; //数组大小增加1 - } - - /** - * 将对象o添加到ArrayList的指定位置. - * @param index: 指定位置. - * @param o: 需要添加的对象. - */ - public void add(int index, Object o) { - ensureCapacity(size + 1); //确保数组的容量可以装的下size + 1个元素,如果不够则扩容 - - System.arraycopy(elementData, index, elementData, index + 1, size - index); //将index位置到结束位置所有的数组往后移动一个位置 - elementData[index] = o; //将对象o添加到index位置 - size++;//数组大小增加1 - } - - public Object get(int index) { - rangeCheck(index); - return elementData[index]; - } - - public Object remove(int index) { - rangeCheck(index); - - if (index != elementData.length - 1) { - System.arraycopy(elementData, index + 1, elementData, index, size - 1 - index); - } - - size--; - return elementData; - } - - public int size() { - return size; - } - - public Iterator iterator() { - return new ArrayListIterator(this); - } - - private void ensureCapacity(int number) { - if (number > elementData.length) { - elementData = grow(elementData, 1); - } - } - - public Object[] grow(Object[] src, int step) { - Object[] target = new Object[src.length + step]; - System.arraycopy(src, 0, target, 0, src.length); - return target; - } - - public void rangeCheck(int index){ - if (index > size || index < 0) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); - } - } - - private class ArrayListIterator implements Iterator { - ArrayList arrayList = null; - int current = 0; - - private ArrayListIterator(ArrayList arrayList) { - this.arrayList = arrayList; - } - - @Override - public boolean hasNext() { - current++; - return current > arrayList.size() ? false : true; - } - - @Override - public Object next() { - return elementData[current]; - } - - } - - public static void main(String[] args) { - ArrayList arrayList = new ArrayList(); - arrayList.add("s1"); - arrayList.add("s2"); - arrayList.add("s3"); - arrayList.add("s4"); - arrayList.add(3, "s33"); - arrayList.add("s5"); - - System.out.println(arrayList.size()); - - System.out.println(arrayList.get(2)); - - arrayList.remove(3); - - System.out.println(arrayList.size()); - - arrayList.add("s1"); - System.out.println(arrayList.size()); - arrayList.remove(5); - System.out.println(arrayList.size()); - - Iterator it = arrayList.iterator(); - while(it.hasNext()){ - System.out.print(it.next() + " "); - } - System.out.println(); - } - -} diff --git a/group05/284422826/src/com/coderising/download/DownloadThread.java b/group05/284422826/src/main/java/com/coderising/download/DownloadThread.java similarity index 100% rename from group05/284422826/src/com/coderising/download/DownloadThread.java rename to group05/284422826/src/main/java/com/coderising/download/DownloadThread.java diff --git a/group05/284422826/src/com/coderising/download/FileDownloader.java b/group05/284422826/src/main/java/com/coderising/download/FileDownloader.java similarity index 100% rename from group05/284422826/src/com/coderising/download/FileDownloader.java rename to group05/284422826/src/main/java/com/coderising/download/FileDownloader.java diff --git a/group05/284422826/src/com/coderising/download/FileDownloaderTest.java b/group05/284422826/src/main/java/com/coderising/download/FileDownloaderTest.java similarity index 100% rename from group05/284422826/src/com/coderising/download/FileDownloaderTest.java rename to group05/284422826/src/main/java/com/coderising/download/FileDownloaderTest.java diff --git a/group05/284422826/src/main/java/com/coderising/download/api/Connection.java b/group05/284422826/src/main/java/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..622dc26bc6 --- /dev/null +++ b/group05/284422826/src/main/java/com/coderising/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coderising.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + byte[] read(int startPos, int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + int getContentLength(); + + /** + * 关闭连接 + */ + void close(); +} diff --git a/group05/284422826/src/com/coderising/download/api/ConnectionException.java b/group05/284422826/src/main/java/com/coderising/download/api/ConnectionException.java similarity index 100% rename from group05/284422826/src/com/coderising/download/api/ConnectionException.java rename to group05/284422826/src/main/java/com/coderising/download/api/ConnectionException.java diff --git a/group05/284422826/src/main/java/com/coderising/download/api/ConnectionManager.java b/group05/284422826/src/main/java/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..a478bd3d2d --- /dev/null +++ b/group05/284422826/src/main/java/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + Connection open(String url) throws ConnectionException; +} diff --git a/group05/284422826/src/main/java/com/coderising/download/api/DownloadListener.java b/group05/284422826/src/main/java/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..de81b7607d --- /dev/null +++ b/group05/284422826/src/main/java/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public interface DownloadListener { + void notifyFinished(); +} diff --git a/group05/284422826/src/com/coderising/download/impl/ConnectionImpl.java b/group05/284422826/src/main/java/com/coderising/download/impl/ConnectionImpl.java similarity index 100% rename from group05/284422826/src/com/coderising/download/impl/ConnectionImpl.java rename to group05/284422826/src/main/java/com/coderising/download/impl/ConnectionImpl.java diff --git a/group05/284422826/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group05/284422826/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java similarity index 100% rename from group05/284422826/src/com/coderising/download/impl/ConnectionManagerImpl.java rename to group05/284422826/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/clz/AccessFlag.java b/group05/284422826/src/main/java/com/coderising/jvm/clz/AccessFlag.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/clz/AccessFlag.java rename to group05/284422826/src/main/java/com/coderising/jvm/clz/AccessFlag.java diff --git a/group05/284422826/src/main/java/com/coderising/jvm/clz/ClassFile.java b/group05/284422826/src/main/java/com/coderising/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..650ca8375d --- /dev/null +++ b/group05/284422826/src/main/java/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,75 @@ +package com.coderising.jvm.clz; + +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + + System.out.println("Super Class Name:"+ getSuperClassName()); + + + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassIndex.java b/group05/284422826/src/main/java/com/coderising/jvm/clz/ClassIndex.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassIndex.java rename to group05/284422826/src/main/java/com/coderising/jvm/clz/ClassIndex.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/ClassInfo.java b/group05/284422826/src/main/java/com/coderising/jvm/constant/ClassInfo.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/constant/ClassInfo.java rename to group05/284422826/src/main/java/com/coderising/jvm/constant/ClassInfo.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantInfo.java b/group05/284422826/src/main/java/com/coderising/jvm/constant/ConstantInfo.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantInfo.java rename to group05/284422826/src/main/java/com/coderising/jvm/constant/ConstantInfo.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantPool.java b/group05/284422826/src/main/java/com/coderising/jvm/constant/ConstantPool.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantPool.java rename to group05/284422826/src/main/java/com/coderising/jvm/constant/ConstantPool.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/FieldRefInfo.java b/group05/284422826/src/main/java/com/coderising/jvm/constant/FieldRefInfo.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/constant/FieldRefInfo.java rename to group05/284422826/src/main/java/com/coderising/jvm/constant/FieldRefInfo.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/MethodRefInfo.java b/group05/284422826/src/main/java/com/coderising/jvm/constant/MethodRefInfo.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/constant/MethodRefInfo.java rename to group05/284422826/src/main/java/com/coderising/jvm/constant/MethodRefInfo.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java b/group05/284422826/src/main/java/com/coderising/jvm/constant/NameAndTypeInfo.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java rename to group05/284422826/src/main/java/com/coderising/jvm/constant/NameAndTypeInfo.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/NullConstantInfo.java b/group05/284422826/src/main/java/com/coderising/jvm/constant/NullConstantInfo.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/constant/NullConstantInfo.java rename to group05/284422826/src/main/java/com/coderising/jvm/constant/NullConstantInfo.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/StringInfo.java b/group05/284422826/src/main/java/com/coderising/jvm/constant/StringInfo.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/constant/StringInfo.java rename to group05/284422826/src/main/java/com/coderising/jvm/constant/StringInfo.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/UTF8Info.java b/group05/284422826/src/main/java/com/coderising/jvm/constant/UTF8Info.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/constant/UTF8Info.java rename to group05/284422826/src/main/java/com/coderising/jvm/constant/UTF8Info.java diff --git a/group05/284422826/src/main/java/com/coderising/jvm/loader/ByteCodeIterator.java b/group05/284422826/src/main/java/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..d15af81630 --- /dev/null +++ b/group05/284422826/src/main/java/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,54 @@ +package com.coderising.jvm.loader; + +import com.coderising.jvm.util.Util; + +import java.util.Arrays; + + +public class ByteCodeIterator { + byte[] codes; + int pos = 0; + + public ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public byte[] getBytes(int len) { + if (pos + len >= codes.length) { + throw new ArrayIndexOutOfBoundsException(); + } + + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos = pos + len; + return data; + } + + public int nextU1toInt() { + return Util.byteToInt(new byte[]{codes[pos++]}); + } + + public int nextU2toInt() { + return Util.byteToInt(new byte[]{codes[pos++], codes[pos++]}); + } + + public int nextU4toInt() { + return Util.byteToInt(new byte[]{codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextU4ToHexString(){ + return Util.byteToHexString(new byte[]{codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextUxToHexString(int len){ + byte[] temp = new byte[len]; + for (int i = 0; i < len; i++) { + temp[i] = codes[pos++]; + } + return Util.byteToHexString(temp).toLowerCase(); + } + + public void back(int n){ + pos = pos - n; + } + +} diff --git a/group05/284422826/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java b/group05/284422826/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..0560d27c8a --- /dev/null +++ b/group05/284422826/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,136 @@ +package com.coderising.jvm.loader; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.clz.ClassFile; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + className = className.replace('.', File.separatorChar) +".class"; + + for(String path : this.clzPaths){ + + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if(codes != null){ + return codes; + } + } + + return null; + + + + } + + private byte[] loadClassFile(String clzFileName) { + + File f = new File(clzFileName); + + try { + + return IOUtils.toByteArray(new FileInputStream(f)); + + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + + + public void addClassPath(String path) { + if(this.clzPaths.contains(path)){ + return; + } + + this.clzPaths.add(path); + + } + + + + public String getClassPath(){ + return StringUtils.join(this.clzPaths,";"); + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + + + + // ------------------------------backup------------------------ + public String getClassPath_V1(){ + + StringBuffer buffer = new StringBuffer(); + for(int i=0;i", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + + +} diff --git a/group05/284422826/src/com/coderising/jvm/test/EmployeeV1.java b/group05/284422826/src/main/java/com/coderising/jvm/test/EmployeeV1.java similarity index 100% rename from group05/284422826/src/com/coderising/jvm/test/EmployeeV1.java rename to group05/284422826/src/main/java/com/coderising/jvm/test/EmployeeV1.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/util/Util.java b/group05/284422826/src/main/java/com/coderising/jvm/util/Util.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/util/Util.java rename to group05/284422826/src/main/java/com/coderising/jvm/util/Util.java diff --git a/group05/284422826/src/com/coderising/litestruts/LoginAction.java b/group05/284422826/src/main/java/com/coderising/litestruts/LoginAction.java similarity index 100% rename from group05/284422826/src/com/coderising/litestruts/LoginAction.java rename to group05/284422826/src/main/java/com/coderising/litestruts/LoginAction.java diff --git a/group05/284422826/src/com/coderising/litestruts/Struts.java b/group05/284422826/src/main/java/com/coderising/litestruts/Struts.java similarity index 100% rename from group05/284422826/src/com/coderising/litestruts/Struts.java rename to group05/284422826/src/main/java/com/coderising/litestruts/Struts.java diff --git a/group05/284422826/src/com/coderising/litestruts/StrutsTest.java b/group05/284422826/src/main/java/com/coderising/litestruts/StrutsTest.java similarity index 100% rename from group05/284422826/src/com/coderising/litestruts/StrutsTest.java rename to group05/284422826/src/main/java/com/coderising/litestruts/StrutsTest.java diff --git a/group05/284422826/src/com/coderising/litestruts/View.java b/group05/284422826/src/main/java/com/coderising/litestruts/View.java similarity index 100% rename from group05/284422826/src/com/coderising/litestruts/View.java rename to group05/284422826/src/main/java/com/coderising/litestruts/View.java diff --git a/group05/284422826/src/com/coding2017/basic/BinaryTreeNode.java b/group05/284422826/src/main/java/com/coding2017/basic/BinaryTreeNode.java similarity index 100% rename from group05/284422826/src/com/coding2017/basic/BinaryTreeNode.java rename to group05/284422826/src/main/java/com/coding2017/basic/BinaryTreeNode.java diff --git a/group05/284422826/src/main/java/com/coding2017/basic/Iterator.java b/group05/284422826/src/main/java/com/coding2017/basic/Iterator.java new file mode 100644 index 0000000000..939c382551 --- /dev/null +++ b/group05/284422826/src/main/java/com/coding2017/basic/Iterator.java @@ -0,0 +1,7 @@ +package com.coding2017.basic; + +public interface Iterator { + boolean hasNext(); + Object next(); + +} diff --git a/group05/284422826/src/main/java/com/coding2017/basic/List.java b/group05/284422826/src/main/java/com/coding2017/basic/List.java new file mode 100644 index 0000000000..0b6a48e7e4 --- /dev/null +++ b/group05/284422826/src/main/java/com/coding2017/basic/List.java @@ -0,0 +1,9 @@ +package com.coding2017.basic; + +public interface List { + void add(Object o); + void add(int index, Object o); + Object get(int index); + Object remove(int index); + int size(); +} diff --git a/group05/284422826/src/com/coding2017/basic/Queue.java b/group05/284422826/src/main/java/com/coding2017/basic/Queue.java similarity index 100% rename from group05/284422826/src/com/coding2017/basic/Queue.java rename to group05/284422826/src/main/java/com/coding2017/basic/Queue.java diff --git a/group05/284422826/src/main/java/com/coding2017/basic/array/ArrayList.java b/group05/284422826/src/main/java/com/coding2017/basic/array/ArrayList.java new file mode 100644 index 0000000000..236b3006ac --- /dev/null +++ b/group05/284422826/src/main/java/com/coding2017/basic/array/ArrayList.java @@ -0,0 +1,128 @@ +package com.coding2017.basic; + +/** + * 功能:实现ArrayList. + * @author zhanglifeng. + */ +public class ArrayList implements List { + private int size = 0; //当前数组大小 + + private Object[] elementData = new Object[5]; //初始数组 + + /** + * 将对象o添加到ArrayList中. + * @param o:需要添加的对象. + */ + public void add(Object o) { + ensureCapacity(size + 1); //确保数组的容量可以装的下size + 1个元素,如果不够则扩容 + + elementData[size] = o; //将o添加到数组中 + size++; //数组大小增加1 + } + + /** + * 将对象o添加到ArrayList的指定位置. + * @param index: 指定位置. + * @param o: 需要添加的对象. + */ + public void add(int index, Object o) { + ensureCapacity(size + 1); //确保数组的容量可以装的下size + 1个元素,如果不够则扩容 + + System.arraycopy(elementData, index, elementData, index + 1, size - index); //将index位置到结束位置所有的数组往后移动一个位置 + elementData[index] = o; //将对象o添加到index位置 + size++;//数组大小增加1 + } + + public Object get(int index) { + rangeCheck(index); + return elementData[index]; + } + + public Object remove(int index) { + rangeCheck(index); + + if (index != elementData.length - 1) { + System.arraycopy(elementData, index + 1, elementData, index, size - 1 - index); + } + + size--; + return elementData; + } + + public int size() { + return size; + } + + public Iterator iterator() { + return new ArrayListIterator(this); + } + + private void ensureCapacity(int number) { + if (number > elementData.length) { + elementData = grow(elementData, 1); + } + } + + public Object[] grow(Object[] src, int step) { + Object[] target = new Object[src.length + step]; + System.arraycopy(src, 0, target, 0, src.length); + return target; + } + + public void rangeCheck(int index){ + if (index > size || index < 0) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + } + } + + private class ArrayListIterator implements Iterator { + ArrayList arrayList = null; + int current = 0; + + private ArrayListIterator(ArrayList arrayList) { + this.arrayList = arrayList; + } + + @Override + public boolean hasNext() { + current++; + return current <= arrayList.size(); + } + + @Override + public Object next() { + return elementData[current]; + } + + } + + public static void main(String[] args) { + ArrayList arrayList = new ArrayList(); + arrayList.add("s1"); + arrayList.add("s2"); + arrayList.add("s3"); + arrayList.add("s4"); + arrayList.add(3, "s33"); + arrayList.add("s5"); + + System.out.println(arrayList.size()); + + System.out.println(arrayList.get(2)); + + arrayList.remove(3); + + System.out.println(arrayList.size()); + + arrayList.add("s1"); + System.out.println(arrayList.size()); + arrayList.remove(5); + System.out.println(arrayList.size()); + + Iterator it = arrayList.iterator(); + while(it.hasNext()){ + System.out.print(it.next() + " "); + } + System.out.println(); + } + +} diff --git a/group05/284422826/src/com/coding2017/basic/array/ArrayUtil.java b/group05/284422826/src/main/java/com/coding2017/basic/array/ArrayUtil.java similarity index 100% rename from group05/284422826/src/com/coding2017/basic/array/ArrayUtil.java rename to group05/284422826/src/main/java/com/coding2017/basic/array/ArrayUtil.java diff --git a/group05/284422826/src/com/coding2017/basic/array/ArrayUtilTest.java b/group05/284422826/src/main/java/com/coding2017/basic/array/ArrayUtilTest.java similarity index 100% rename from group05/284422826/src/com/coding2017/basic/array/ArrayUtilTest.java rename to group05/284422826/src/main/java/com/coding2017/basic/array/ArrayUtilTest.java diff --git a/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrame.java b/group05/284422826/src/main/java/com/coding2017/basic/linklist/LRUPageFrame.java similarity index 100% rename from group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrame.java rename to group05/284422826/src/main/java/com/coding2017/basic/linklist/LRUPageFrame.java diff --git a/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrameTest.java b/group05/284422826/src/main/java/com/coding2017/basic/linklist/LRUPageFrameTest.java similarity index 100% rename from group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrameTest.java rename to group05/284422826/src/main/java/com/coding2017/basic/linklist/LRUPageFrameTest.java diff --git a/group05/284422826/src/com/coding2017/basic/linklist/LinkedList.java b/group05/284422826/src/main/java/com/coding2017/basic/linklist/LinkedList.java similarity index 100% rename from group05/284422826/src/com/coding2017/basic/linklist/LinkedList.java rename to group05/284422826/src/main/java/com/coding2017/basic/linklist/LinkedList.java diff --git a/group05/284422826/src/com/coding2017/basic/Stack.java b/group05/284422826/src/main/java/com/coding2017/basic/stack/Stack.java similarity index 100% rename from group05/284422826/src/com/coding2017/basic/Stack.java rename to group05/284422826/src/main/java/com/coding2017/basic/stack/Stack.java diff --git a/group05/284422826/src/main/java/com/coding2017/basic/stack/StackUtil.java b/group05/284422826/src/main/java/com/coding2017/basic/stack/StackUtil.java new file mode 100644 index 0000000000..c14ddd9039 --- /dev/null +++ b/group05/284422826/src/main/java/com/coding2017/basic/stack/StackUtil.java @@ -0,0 +1,116 @@ +package com.coding2017.basic.stack; + +import java.util.Stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if (s == null || s.isEmpty()) { + return; + } + + Integer top = s.pop(); + reverse(s); + addToBottom(s, top); + } + + public static void addToBottom(Stack s, Integer value) { + if(s.isEmpty()){ + s.push(value); + }else { + Integer top = s.pop(); + addToBottom(s, value); + s.push(top); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s, Object o) { + if(s == null || s.isEmpty()){ + return; + } + Stack tempStack = new Stack(); + while(!s.isEmpty()){ + Object value = s.pop(); + if (!value.equals(o)) { + tempStack.push(value); + } + } + + while(!tempStack.isEmpty()){ + s.push(tempStack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param len + * @return + */ + public static Object[] getTop(Stack s, int len) { + if(s == null || s.isEmpty() || s.size() < len || len <= 0){ + return null; + } + + Object[] result = new Object[len]; + int i = 0; + while(!s.isEmpty()){ + Object value = s.pop(); + result[i++] = value; + if(i == len){ + break; + } + } + + return result; + } + + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + Stack stack = new Stack(); + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if(c == '(' || c == '{' || c == '['){ + stack.push(c); + }else if(c == ')'){ + char topChar = stack.pop(); + if(topChar != '('){ + return false; + } + }else if(c == ']'){ + char topChar = stack.pop(); + if(topChar != '['){ + return false; + } + }else if(c == '}'){ + char topChar = stack.pop(); + if(topChar != '{'){ + return false; + } + } + } + return stack.size() == 0; + } + + +} diff --git a/group05/284422826/src/main/java/com/coding2017/basic/stack/StackUtilTest.java b/group05/284422826/src/main/java/com/coding2017/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..96179918cb --- /dev/null +++ b/group05/284422826/src/main/java/com/coding2017/basic/stack/StackUtilTest.java @@ -0,0 +1,78 @@ +package com.coding2017.basic.stack; + +import static org.junit.Assert.fail; + +import java.util.Stack; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +public class StackUtilTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAddToBottom() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + + StackUtil.addToBottom(s, 0); + + Assert.assertEquals("[0, 1, 2, 3]", s.toString()); + + } + @Test + public void testReverse() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString()); + StackUtil.reverse(s); + Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString()); + } + + @Test + public void testRemove() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + StackUtil.remove(s, 2); + Assert.assertEquals("[1, 3]", s.toString()); + } + + @Test + public void testGetTop() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + { + Object[] values = StackUtil.getTop(s, 3); + Assert.assertEquals(5, values[0]); + Assert.assertEquals(4, values[1]); + Assert.assertEquals(3, values[2]); + } + } + + @Test + public void testIsValidPairs() { + Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])")); + Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})")); + } + +} diff --git a/group05/578505552/578505552.iml b/group05/578505552/578505552.iml deleted file mode 100644 index 95e7551d7a..0000000000 --- a/group05/578505552/578505552.iml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/group05/578505552/pom.xml b/group05/578505552/pom.xml index 62eed92daf..ea3686ca26 100644 --- a/group05/578505552/pom.xml +++ b/group05/578505552/pom.xml @@ -7,7 +7,6 @@ 1.0-SNAPSHOT jar - basic http://maven.apache.org diff --git a/group05/578505552/src/main/java/com/coderising/array/ArrayUtil.java b/group05/578505552/src/main/java/com/coderising/array/ArrayUtil.java deleted file mode 100644 index 2c248db331..0000000000 --- a/group05/578505552/src/main/java/com/coderising/array/ArrayUtil.java +++ /dev/null @@ -1,242 +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){ - int length = origin.length; - int i = 0; - int j = length - 1; - while (i < j){ - int tmp = origin[i]; - origin[i] = origin[j]; - origin[j] = tmp; - i++; - j--; - } - } - - /** - * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} - * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: - * {1,3,4,5,6,6,5,4,7,6,7,5} - * @param oldArray - * @return - */ - - public int[] removeZero(int[] oldArray){ - int length = oldArray.length; - int[] newArray = new int[length]; - int j = 0; - for (int i = 0; i < length; i++) { - if (oldArray[i] != 0){ - newArray[j++] = oldArray[i]; - } - } - int[] res = new int[j]; - System.arraycopy(newArray, 0, res, 0, j); - return res; - } - - /** - * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 - * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 - * @param array1 - * @param array2 - * @return - */ - - public int[] merge(int[] array1, int[] array2){ - int length1 = array1.length; - int length2 = array2.length; - int i = 0; - int j = 0; - - int[] res = new int[length1 + length2]; - int k = 0; - while (i < length1 || j < length2){ - int next = Integer.MIN_VALUE; - if (i < length1 && j < length2){ - if (array1[i] == array2[j]){ - next = array1[i]; - i++; - j++; - } else if (array1[i] < array2[j]){ - next = array1[i++]; - } else { - next = array2[j++]; - } - } else if (i < length1){ - next = array1[i++]; - } else { - next = array2[j++]; - } - - if (k == 0){ - res[k++] = next; - } else if (next > res[k-1]){ - res[k++] = next; - } - } - - int[] merged = new int[k]; - System.arraycopy(res, 0, merged, 0, k); - return merged; - } - /** - * 把一个已经存满数据的数组 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 IllegalArgumentException("illegal size"); - } - int newLength = oldArray.length + size; - int[] newArray = new int[newLength]; - 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){ - - if (max <= 1){ - return new int[0]; - } - - int[] res = new int[max]; - int i = 1; - int j = 1; - int k = 0; - res[k++] = 1; - res[k++] = 1; - - int tmp = i + j; - while (tmp < max){ - res[k++] = tmp; - i = j; - j = tmp; - tmp = i + j; - } - - int[] result = new int[k]; - System.arraycopy(res, 0, result, 0, k); - return result; - } - - /** - * 返回小于给定最大值max的所有素数数组 - * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] - * @param max - * @return - */ - public int[] getPrimes(int max){ - if (max < 0){ - return new int[0]; - } - int[] res = new int[max]; - int k = 0; - for (int i = 2; i < max; i++) { - if (isPrime(i)){ - res[k++] = i; - } - } - int[] result = new int[k]; - System.arraycopy(res, 0, result, 0, k); - return result; - } - - private boolean isPrime(int num){ - - if (num < 1){ - return false; - } - for (int i = 2; i <= num / 2; i++) { - if (num % i == 0){ - return false; - } - - } - return true; - } - - /** - * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 - * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 - * @param max - * @return - */ - public int[] getPerfectNumbers(int max){ - - if (max < 0){ - return new int[0]; - } - int[] res = new int[max]; - int k = 0; - for (int i = 0; i < max; i++) { - if (isPerfectNumbers(i)){ - res[k++] = i; - } - } - int[] result = new int[k]; - System.arraycopy(res, 0, result, 0, k); - return result; - } - - private boolean isPerfectNumbers(int num){ - - return num == getFactorSum(num); - } - - private int getFactorSum(int num){ - if (num == 0 || num == 1){ - return -1; - } - int sum = 0; - for (int i = 1; i <= num / 2; i++) { - if (num % i == 0){ - sum += i; - } - } - return sum; - } - /** - * 用seperator 把数组 array给连接起来 - * 例如array= [3,8,9], seperator = "-" - * 则返回值为"3-8-9" - * @param array - * @param separator - * @return - */ - public String join(int[] array, String separator){ - - if (array.length <= 0){ - return ""; - } - - StringBuffer stringBuffer = new StringBuffer(); - for (int i = 0; i < array.length - 1; i++) { - stringBuffer.append(String.valueOf(array[i])).append(separator); - } - stringBuffer.append(String.valueOf(array[array.length-1])); - return stringBuffer.toString(); - } - -} diff --git a/group05/578505552/src/main/java/com/coderising/download/DownloadThread.java b/group05/578505552/src/main/java/com/coderising/download/DownloadThread.java deleted file mode 100644 index feefc27cfc..0000000000 --- a/group05/578505552/src/main/java/com/coderising/download/DownloadThread.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.coderising.download; - -import com.coderising.download.api.Connection; -import com.coderising.download.api.DownloadListener; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; - -public class DownloadThread extends Thread{ - - Connection conn; - int startPos; - int endPos; - File targetFile; - DownloadListener listener; - - public DownloadThread(Connection conn, int startPos, int endPos, File targetFile, DownloadListener listener){ - this.conn = conn; - this.startPos = startPos; - this.endPos = endPos; - this.targetFile = targetFile; - this.listener = listener; - } - public void run(){ - try { - System.out.println("线程" + this.getName() + "正在下载" + startPos + "--" + endPos + "的数据"); - - byte[] content = conn.read(startPos, endPos); - RandomAccessFile randomAccessFile = new RandomAccessFile(targetFile, "rw"); - randomAccessFile.seek(startPos); - randomAccessFile.write(content, 0, endPos - startPos + 1); - randomAccessFile.close(); - - System.out.println("线程" + this.getName() + "完成" + startPos + "--" + endPos + "数据的下载"); - - if (FileDownloader.isDownLoadFinished()){ - listener.notifyFinished(); - System.out.println(">>>>>>>>>>>>>>线程" + this.getName() + "完成了最终的下载"); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - conn.close(); - } - } -} diff --git a/group05/578505552/src/main/java/com/coderising/download/FileDownloader.java b/group05/578505552/src/main/java/com/coderising/download/FileDownloader.java deleted file mode 100644 index d399381a7a..0000000000 --- a/group05/578505552/src/main/java/com/coderising/download/FileDownloader.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.coderising.download; - -import com.coderising.download.api.Connection; -import com.coderising.download.api.ConnectionException; -import com.coderising.download.api.ConnectionManager; -import com.coderising.download.api.DownloadListener; - -import java.io.File; - -public class FileDownloader { - - String url; - DownloadListener listener; - ConnectionManager cm; - public static final int threadCount = 5; - private static int threadFinished; - - public FileDownloader(String _url) { - this.url = _url; - } - - public void execute(){ - try { - Connection conn = cm.open(this.url); - int length = conn.getContentLength(); - - File targetFile = new File("D:" + File.separator + getFileName()); - System.out.println("总长度:" + length); - - int temp = length / threadCount; - for (int i = 0; i < threadCount; i++) { - int startPos = i * temp; - int endPos = startPos + temp - 1; - if (i == threadCount - 1){ - endPos = length; - } - String threadName = "DownloadThread" + String.valueOf(i); - Connection connection = cm.open(url); - DownloadThread downloadThread = new DownloadThread(connection, startPos, endPos, targetFile, listener); - downloadThread.setName(threadName); - downloadThread.start(); - } - } catch (ConnectionException e) { - e.printStackTrace(); - } finally{ - - } - } - - public String getFileName(){ - return "meinv.jpg"; - } - - public synchronized static boolean isDownLoadFinished(){ - threadFinished++; - return threadFinished == threadCount; - } - - public void setListener(DownloadListener listener) { - this.listener = listener; - } - - public void setConnectionManager(ConnectionManager ucm){ - this.cm = ucm; - } -} diff --git a/group05/578505552/src/main/java/com/coderising/download/FileDownloaderTest.java b/group05/578505552/src/main/java/com/coderising/download/FileDownloaderTest.java deleted file mode 100644 index 6f740c3882..0000000000 --- a/group05/578505552/src/main/java/com/coderising/download/FileDownloaderTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.coderising.download; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.coderising.download.api.ConnectionManager; -import com.coderising.download.api.DownloadListener; -import com.coderising.download.impl.ConnectionManagerImpl; - -public class FileDownloaderTest { - boolean downloadFinished = false; - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testDownload() { - - String url = "https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/image/h%3D360/sign=9bb90992550fd9f9bf17536f152cd42b/9a504fc2d5628535959cf4cf94ef76c6a6ef63db.jpg"; - - FileDownloader downloader = new FileDownloader(url); - ConnectionManager cm = new ConnectionManagerImpl(); - downloader.setConnectionManager(cm); - downloader.setListener(new DownloadListener() { - public void notifyFinished() { - downloadFinished = true; - } - }); - downloader.execute(); - - // 等待多线程下载程序执行完毕 - while (!downloadFinished) { - try { - System.out.println("还没有下载完成,休眠五秒"); - //休眠5秒 - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - System.out.println("下载完成!"); - } - -} diff --git a/group05/578505552/src/main/java/com/coderising/download/api/Connection.java b/group05/578505552/src/main/java/com/coderising/download/api/Connection.java deleted file mode 100644 index 494c713b27..0000000000 --- a/group05/578505552/src/main/java/com/coderising/download/api/Connection.java +++ /dev/null @@ -1,23 +0,0 @@ -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/group05/578505552/src/main/java/com/coderising/download/api/ConnectionException.java b/group05/578505552/src/main/java/com/coderising/download/api/ConnectionException.java deleted file mode 100644 index 5954d22409..0000000000 --- a/group05/578505552/src/main/java/com/coderising/download/api/ConnectionException.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.coderising.download.api; - -public class ConnectionException extends Exception { - - public ConnectionException() { - } - - public ConnectionException(String message) { - super(message); - } - - public ConnectionException(String message, Throwable cause) { - super(message, cause); - } - - public ConnectionException(Throwable cause) { - super(cause); - } - -} diff --git a/group05/578505552/src/main/java/com/coderising/download/impl/ConnectionImpl.java b/group05/578505552/src/main/java/com/coderising/download/impl/ConnectionImpl.java deleted file mode 100644 index 0561318d7a..0000000000 --- a/group05/578505552/src/main/java/com/coderising/download/impl/ConnectionImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.coderising.download.impl; - -import com.coderising.download.api.Connection; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; - -public class ConnectionImpl implements Connection{ - - private HttpURLConnection conn; - - public ConnectionImpl(HttpURLConnection urlConnection) { - this.conn = urlConnection; - } - - public byte[] read(int startPos, int endPos) throws IOException { - conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); - if (conn.getResponseCode() == 206){ - InputStream inputStream = conn.getInputStream(); - byte[] temp = new byte[endPos - startPos + 1]; - while ((inputStream.read(temp)) != -1){ - - } - return temp; - } - return new byte[0]; - } - - public int getContentLength() { - try { - if (conn.getResponseCode() == 200){ - return conn.getContentLength(); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - this.close(); - } - return 0; - } - - public void close() { - if (conn != null){ - conn.disconnect(); - conn = null; - } - } -} diff --git a/group05/578505552/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java b/group05/578505552/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java deleted file mode 100644 index 3ea9a95517..0000000000 --- a/group05/578505552/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.coderising.download.impl; - -import com.coderising.download.api.Connection; -import com.coderising.download.api.ConnectionException; -import com.coderising.download.api.ConnectionManager; - -import java.net.HttpURLConnection; -import java.net.URL; - -public class ConnectionManagerImpl implements ConnectionManager { - - public Connection open(String url) throws ConnectionException { - - try { - URL urlObject = new URL(url); - HttpURLConnection urlConnection = (HttpURLConnection)urlObject.openConnection(); - urlConnection.setRequestMethod("GET"); - urlConnection.setReadTimeout(5000); - return new ConnectionImpl(urlConnection); - } catch (java.io.IOException e) { - throw new ConnectionException("连接失败"); - } - } - -} diff --git a/group05/578505552/src/main/java/com/coderising/litestruts/Configuration.java b/group05/578505552/src/main/java/com/coderising/litestruts/Configuration.java deleted file mode 100644 index 90d8a0c6a1..0000000000 --- a/group05/578505552/src/main/java/com/coderising/litestruts/Configuration.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.coderising.litestruts; - -/** - * Created by songbao.yang on 2017/3/10. - */ -public class Configuration { -} diff --git a/group05/578505552/src/main/java/com/coderising/litestruts/LoginAction.java b/group05/578505552/src/main/java/com/coderising/litestruts/LoginAction.java deleted file mode 100644 index b74dfa425d..0000000000 --- a/group05/578505552/src/main/java/com/coderising/litestruts/LoginAction.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.coderising.litestruts; - -/** - * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 - * - */ -public class LoginAction{ - private String name ; - private String password; - private String message; - - public String getName() { - return name; - } - - public String getPassword() { - return password; - } - - public String execute(){ - if("test".equals(name) && "1234".equals(password)){ - this.message = "login successful"; - return "success"; - } - this.message = "login failed,please check your user/pwd"; - return "fail"; - } - - public void setName(String name){ - this.name = name; - } - public void setPassword(String password){ - this.password = password; - } - public String getMessage(){ - return this.message; - } -} diff --git a/group05/578505552/src/main/java/com/coderising/litestruts/Struts.java b/group05/578505552/src/main/java/com/coderising/litestruts/Struts.java deleted file mode 100644 index 95b4d37a52..0000000000 --- a/group05/578505552/src/main/java/com/coderising/litestruts/Struts.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.coderising.litestruts; - -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.Element; -import org.dom4j.io.SAXReader; - -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class Struts { - - public static View runAction(String actionName, Map parameters) { - -// 0. 读取配置文件struts.xml - Action action = matchAction(parseXml("/struts.xml"), actionName); - try { - -// 1. 根据actionName找到相对应的class, 通过反射实例化(创建对象), -// 根据parameters中的数据,调用对象的setter方法 - Class clazz = Class.forName(action.getClassName()); - Object instance = clazz.newInstance(); - for (String key : parameters.keySet()){ - try { - PropertyDescriptor propertyDescriptor = new PropertyDescriptor(key, clazz); - Method setMethod = propertyDescriptor.getWriteMethod(); - setMethod.invoke(instance, parameters.get(key)); - } catch (IntrospectionException e) { - e.printStackTrace(); - } - } - -// 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" - Method exectueMethod = null; - String result = null; - try { - exectueMethod = clazz.getMethod("execute"); - result = (String)exectueMethod.invoke(instance); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } - -// 3. 通过反射找到对象的所有getter方法(例如 getMessage), -// 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , -// 放到View对象的parameters - Map hashMap = new HashMap(); - Field[] declaredFields = clazz.getDeclaredFields(); - for (Field field : declaredFields){ - String name = field.getName(); - try { - PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, clazz); - Method getMethod = propertyDescriptor.getReadMethod(); - Object res = getMethod.invoke(instance); - hashMap.put(name, res); - } catch (IntrospectionException e) { - e.printStackTrace(); - } - } - -// 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, -// 放到View对象的jsp字段中。 - View view = new View(); - view.setJsp((String)action.getResults().get(result)); - view.setParameters(hashMap); - return view; - - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - - return null; - } - - private static Element parseXml(String resourcePath){ - - InputStream resourceAsStream = Struts.class.getResourceAsStream(resourcePath); - SAXReader saxReader = new SAXReader(); - try { - Document document = saxReader.read(resourceAsStream); - Element rootElement = document.getRootElement(); - return rootElement; - } catch (DocumentException e) { - e.printStackTrace(); - } - - throw new RuntimeException("fail to parse xml"); - } - - private static Action matchAction(Element rootElement, String actionName){ - - List actions = rootElement.elements("action"); - Iterator iterator = actions.iterator(); - Action action = new Action(); - while (iterator.hasNext()){ - Element actionElement = (Element) iterator.next(); - String nameAttributeValue = actionElement.attributeValue("name"); - if (actionName.equals(nameAttributeValue)){ - action.setName(nameAttributeValue); - action.setClassName(actionElement.attributeValue("class")); - List results = actionElement.elements("result"); - Map resultMap = new HashMap(); - Iterator it = results.iterator(); - while (it.hasNext()){ - Element resultElement = (Element)it.next(); - resultMap.put(resultElement.attributeValue("name"), (String)resultElement.getData()); - } - action.setResults(resultMap); - } - } - - return action; - } - - - - -} diff --git a/group05/578505552/src/main/java/com/coderising/litestruts/View.java b/group05/578505552/src/main/java/com/coderising/litestruts/View.java deleted file mode 100644 index 0194c681f6..0000000000 --- a/group05/578505552/src/main/java/com/coderising/litestruts/View.java +++ /dev/null @@ -1,23 +0,0 @@ -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/group05/578505552/src/main/java/com/coding/basic/ArrayList.java b/group05/578505552/src/main/java/com/coding/basic/ArrayList.java deleted file mode 100644 index 54d8f05f02..0000000000 --- a/group05/578505552/src/main/java/com/coding/basic/ArrayList.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.coding.basic; - -import java.util.NoSuchElementException; - -/** - * Created by songbao.yang on 2017/2/21. - * - */ -public class ArrayList implements List { - - private int size = 0; - private Object[] elementData; - private static final int MIN_CAPACITY = 10; - - public ArrayList(int size) { - if (size < 0){ - throw new IllegalArgumentException("illega size: " + size); - } - this.elementData = new Object[size]; - } - - public ArrayList() { - this.elementData = new Object[0]; - } - - public void add(Object o){ - ensureCapacity(size + 1); - elementData[size++] = o; - } - - private void ensureCapacity(int minCapacity){ - if (minCapacity < 0 ){ - throw new OutOfMemoryError(); - } - - int newCapcity = size; - if(minCapacity < MIN_CAPACITY){ - newCapcity = MIN_CAPACITY; - } else if(minCapacity > elementData.length){ - int tmp = elementData.length << 1; - newCapcity = tmp > elementData.length ? tmp : Integer.MAX_VALUE; - } - - newCapcity = minCapacity; - Object[] newData = new Object[newCapcity]; - System.arraycopy(elementData, 0, newData, 0, size); - elementData = newData; - } - - public void add(int index, Object o){ - indexCheck(index); - ensureCapacity(size+1); - System.arraycopy(elementData, index, elementData, index+1, size-index); - elementData[index] = o; - size++; - } - - public Object get(int index){ - indexCheck(index); - return elementData[index]; - } - - private void indexCheck(int index){ - if(index < 0){ - throw new IllegalArgumentException("illegal index: " + index); - } - if(index >= size){ - throw new IndexOutOfBoundsException(); - } - } - - public Object remove(int index){ - indexCheck(index); - Object rm = elementData[index]; - System.arraycopy(elementData, index+1, elementData, index, size-index-1); - size--; - return rm; - } - - public int size(){ - return size; - } - - public Iterator iterator(){ - return new Itr(); - } - - //静态内部类的访问权限不同有何区别?? - private class Itr implements Iterator{ - private int cursor = 0; - - public boolean hasNext() { - return cursor != size; - } - - public Object next() { - if (hasNext()){ - return elementData[cursor++]; - } - throw new NoSuchElementException(); - } - } -} diff --git a/group05/578505552/src/main/java/com/coding/basic/BinaryTreeNode.java b/group05/578505552/src/main/java/com/coding/basic/BinaryTreeNode.java deleted file mode 100644 index 3a36db4031..0000000000 --- a/group05/578505552/src/main/java/com/coding/basic/BinaryTreeNode.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.coding.basic; - -/** - * Created by songbao.yang on 2017/2/21. - * - */ -public class BinaryTreeNode { - - private Integer data; - private BinaryTreeNode left; - private BinaryTreeNode right; - - public Object getData() { - return data; - } - public void setData(Integer 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(Integer o){ - if (o == null){ - throw new IllegalArgumentException("can not insert null"); - } - - BinaryTreeNode newNode = new BinaryTreeNode(); - newNode.data = o; - newNode.left = null; - newNode.right = null; - - BinaryTreeNode cursor = this; - BinaryTreeNode pre = cursor; - while (cursor != null){ - pre = cursor; - if (o.compareTo(cursor.data) < 0){ - cursor = cursor.left; - } else { - cursor = cursor.right; - } - } - - if (o.compareTo(pre.data) < 0){ - pre.left = newNode; - } else { - pre.right = newNode; - } - return this; - } -} diff --git a/group05/578505552/src/main/java/com/coding/basic/Iterator.java b/group05/578505552/src/main/java/com/coding/basic/Iterator.java deleted file mode 100644 index 6765eae519..0000000000 --- a/group05/578505552/src/main/java/com/coding/basic/Iterator.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.coding.basic; - -/** - * Created by songbao.yang on 2017/2/21. - * - */ -public interface Iterator { - public boolean hasNext(); - public Object next(); - -} diff --git a/group05/578505552/src/main/java/com/coding/basic/LinkedList.java b/group05/578505552/src/main/java/com/coding/basic/LinkedList.java deleted file mode 100644 index d1fa42bf4c..0000000000 --- a/group05/578505552/src/main/java/com/coding/basic/LinkedList.java +++ /dev/null @@ -1,156 +0,0 @@ -package com.coding.basic; - -import java.util.NoSuchElementException; - -/** - * Created by songbao.yang on 2017/2/21. - * - */ -public class LinkedList implements List { - - private Node head; - private int elementCount; - - //head作为一个节点,其next的值指向List中真正的第一个节点 - public LinkedList() { - head = new Node(); - head.next = null; - head.data = null; - elementCount = 0; - } - - public void add(Object o){ - Node newNode = new Node(); - newNode.data = o; - newNode.next = null; - - Node cursor = head; - while (cursor.next != null){ - cursor = cursor.next; - } - cursor.next = newNode; - elementCount++; - } - - - public void add(int index , Object o){ - indexRangeCheck(index); - Node newNode = new Node(); - newNode.data = o; - - Node cursor = head; - for (int i = 0; i < index; i++) { - cursor = cursor.next; //将cursor移动到index-1节点处; - } - - newNode.next = cursor.next; //将新节点指向原index处的节点 - cursor.next = newNode;//将原index-1处的节点指向新节点 - elementCount++; - } - - private void indexRangeCheck(int index){ - if (index < 0 || index >= size()){ - throw new IndexOutOfBoundsException(); - } - } - - public Object get(int index){ - indexRangeCheck(index); - Node cursor = head; - for (int i = 0; i < index; i++) { - cursor = cursor.next; - } - return cursor.next.data; - } - - public Object remove(int index){ - indexRangeCheck(index); - Node cursor = head; - for (int i = 0; i < index; i++) { - cursor = cursor.next; - } - Node indexNode = cursor.next; - cursor.next = indexNode.next; - elementCount--; - return indexNode; - } - - public int size(){ - return elementCount; - } - - public void addFirst(Object o){ - Node node = new Node(); - node.data = o; - node.next = head.next; - head.next = node; - elementCount++; - } - - public void addLast(Object o){ - - Node cursor = head; - while (cursor.next != null){ - cursor = cursor.next; - } - Node newNode = new Node(); - newNode.data = o; - newNode.next = null; - cursor.next = newNode; - elementCount++; - } - - public Object removeFirst(){ - - if (size() == 0){ - throw new RuntimeException("no element in list"); - } - Node firstNode = head.next; - head.next = head.next.next; - elementCount--; - return firstNode; - } - - public Object removeLast(){ - if (size() == 0){ - throw new RuntimeException("no element in list"); - } - - Node cursor = head; - for (int i = 0; i < size() - 1; i++) { - cursor = cursor.next; - } - - Node lastNode = cursor.next; - cursor.next = null; - elementCount--; - - return lastNode; - } - - public Iterator iterator(){ - return new Itr(); - } - - private class Itr implements Iterator { - - private Node itrCursor = head; - - public boolean hasNext() { - - return itrCursor.next != null; - } - - public Object next() { - if (hasNext()){ - return itrCursor.next; - } - throw new NoSuchElementException(); - } - } - - private static class Node{ - Object data; - Node next; - } -} diff --git a/group05/578505552/src/main/java/com/coding/basic/List.java b/group05/578505552/src/main/java/com/coding/basic/List.java deleted file mode 100644 index e26fbe7c98..0000000000 --- a/group05/578505552/src/main/java/com/coding/basic/List.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.coding.basic; - -/** - * Created by songbao.yang on 2017/2/21. - * - */ -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(); - public Iterator iterator(); -} diff --git a/group05/578505552/src/main/java/com/coding/basic/Queue.java b/group05/578505552/src/main/java/com/coding/basic/Queue.java deleted file mode 100644 index ec31573ee7..0000000000 --- a/group05/578505552/src/main/java/com/coding/basic/Queue.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.coding.basic; - -import java.util.NoSuchElementException; - -/** - * Created by songbao.yang on 2017/2/22. - * - */ -public class Queue { - - private Object[] elementData; - private int head; //对头的位置 - private int tail; //队尾的位置 - private int size; //队列中元素的个数 - private static final int MIN_INITIAL_CAPACITY = 10; - - public Queue() { - this.elementData = new Object[MIN_INITIAL_CAPACITY]; - this.head = 0; - this.tail = 0; - this.size = 0; - } - - public Queue(int initCapcacity) { - if (initCapcacity < MIN_INITIAL_CAPACITY){ - initCapcacity = MIN_INITIAL_CAPACITY; - } - this.elementData = new Object[initCapcacity]; - this.head = 0; - this.tail = 0; - this.size = 0; - } - - public void enQueue(Object o){ - ensureCapacity(size+1); - if(size != 0){ - tail++; - } - if(tail == elementData.length){ - tail = 0; - } - elementData[tail] = o; - size++; - } - - private void ensureCapacity(int minCapcacity){ - if(minCapcacity <= elementData.length){ - return; - } - - int newCapcacity = elementData.length << 1; - if (newCapcacity < elementData.length){ - newCapcacity = Integer.MAX_VALUE; - } - - Object[] newData = new Object[newCapcacity]; - if(size != 0){ - if(tail >= head){ - System.arraycopy(elementData, head, newData, 0, size); - } else { - System.arraycopy(elementData, head, newData, 0, elementData.length - head); - System.arraycopy(elementData, 0, newData, elementData.length - head, tail + 1); - } - elementData = newData; - head = 0; - tail = this.size - 1; - } - } - - public Object deQueue(){ - if (isEmpty()){ - throw new NoSuchElementException("empty queue"); - } - Object ele = elementData[head]; - size--; - head++; - if(head == elementData.length){ - head = 0; - } - return ele; - } - - public boolean isEmpty(){ - return size == 0; - } - - public int size(){ - return size; - } -} diff --git a/group05/578505552/src/main/java/com/coding/basic/Stack.java b/group05/578505552/src/main/java/com/coding/basic/Stack.java deleted file mode 100644 index ffc4915bef..0000000000 --- a/group05/578505552/src/main/java/com/coding/basic/Stack.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.coding.basic; - - -import java.util.EmptyStackException; - -/** - * Created by songbao.yang on 2017/2/22. - * - */ -public class Stack { - - private Object[] elementData; - private static final int MIN_INITIAL_CAPACITY = 10; - private int cursor; - - public Stack() { - elementData = new Object[MIN_INITIAL_CAPACITY]; - cursor = -1; - } - - public void push(Object o){ - ensureCapacity(size() + 1); - cursor++; - elementData[cursor] = o; - } - - private void ensureCapacity(int minCapacity){ - if(minCapacity <= elementData.length){ - return; - } - - int newSize = elementData.length << 1; - if (newSize < elementData.length){ - newSize = Integer.MAX_VALUE; - } - - Object[] newDataArray = new Object[newSize]; - System.arraycopy(elementData, 0, newDataArray, 0, size()); - elementData = newDataArray; - } - - - public Object pop(){ - Object ele = peek(); - cursor--; - return ele; - } - - public Object peek(){ - if (isEmpty()){ - throw new EmptyStackException(); - } - return elementData[cursor]; - } - - public boolean isEmpty(){ - return size() == 0; - } - - public int size(){ - return cursor + 1; - } -} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/array/ArrayUtil.java b/group05/578505552/src/main/java/dataStruct/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..4a034abf2c --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/array/ArrayUtil.java @@ -0,0 +1,263 @@ +package dataStruct.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){ + return; + } + int length = origin.length; + int i = 0; + int j = length - 1; + while (i < j){ + int tmp = origin[i]; + origin[i] = origin[j]; + origin[j] = tmp; + i++; + j--; + } + } + + /** + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: + * {1,3,4,5,6,6,5,4,7,6,7,5} + * @param oldArray + * @return + */ + + public int[] removeZero(int[] oldArray){ + int length = oldArray.length; + int[] newArray = new int[length]; + int j = 0; + for (int i = 0; i < length; i++) { + if (oldArray[i] != 0){ + newArray[j++] = oldArray[i]; + } + } + int[] res = new int[j]; + System.arraycopy(newArray, 0, res, 0, j); + return res; + } + + /** + * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 + * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * @param array1 + * @param array2 + * @return + */ + + public int[] merge(int[] array1, int[] array2){ + + if(array1 == null && array2 == null){ + return new int[0]; + } + + if (array1 == null){ + return array2; + } + + if (array2 == null){ + return array1; + } + + int length1 = array1.length; + int length2 = array2.length; + int i = 0; + int j = 0; + + int[] res = new int[length1 + length2]; + int k = 0; + while (i < length1 || j < length2){ + int next = Integer.MIN_VALUE; + if (i < length1 && j < length2){ + if (array1[i] == array2[j]){ + next = array1[i]; + i++; + j++; + } else if (array1[i] < array2[j]){ + next = array1[i++]; + } else { + next = array2[j++]; + } + } else if (i < length1){ + next = array1[i++]; + } else { + next = array2[j++]; + } + + if (k == 0){ + res[k++] = next; + } else if (next > res[k-1]){ + res[k++] = next; + } + } + + int[] merged = new int[k]; + System.arraycopy(res, 0, merged, 0, k); + return merged; + } + /** + * 把一个已经存满数据的数组 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 IllegalArgumentException("illegal size"); + } + int newLength = oldArray.length + size; + int[] newArray = new int[newLength]; + 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){ + + if (max <= 1){ + return new int[0]; + } + + int[] res = new int[max]; + int i = 1; + int j = 1; + int k = 0; + res[k++] = 1; + res[k++] = 1; + + int tmp = i + j; + while (tmp < max){ + res[k++] = tmp; + i = j; + j = tmp; + tmp = i + j; + } + + int[] result = new int[k]; + System.arraycopy(res, 0, result, 0, k); + return result; + } + + /** + * 返回小于给定最大值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]; + } + int[] res = new int[max]; + int k = 0; + for (int i = 2; i < max; i++) { + if (isPrime(i)){ + res[k++] = i; + } + } + int[] result = new int[k]; + System.arraycopy(res, 0, result, 0, k); + return result; + } + + private boolean isPrime(int num){ + + if (num < 1){ + return false; + } + for (int i = 2; i <= num / 2; i++) { + if (num % i == 0){ + return false; + } + + } + return true; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + + if (max < 0){ + return new int[0]; + } + int[] res = new int[max]; + int k = 0; + for (int i = 0; i < max; i++) { + if (isPerfectNumbers(i)){ + res[k++] = i; + } + } + int[] result = new int[k]; + System.arraycopy(res, 0, result, 0, k); + return result; + } + + private boolean isPerfectNumbers(int num){ + + return num == getFactorSum(num); + } + + private int getFactorSum(int num){ + if (num == 0 || num == 1){ + return -1; + } + int sum = 0; + for (int i = 1; i <= num / 2; i++) { + if (num % i == 0){ + sum += i; + } + } + return sum; + } + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param separator + * @return + */ + public String join(int[] array, String separator){ + + if (array == null || array.length <= 0){ + return ""; + } + + StringBuffer stringBuffer = new StringBuffer(); + for (int i = 0; i < array.length - 1; i++) { + stringBuffer.append(String.valueOf(array[i])).append(separator); + } + stringBuffer.append(String.valueOf(array[array.length-1])); + return stringBuffer.toString(); + } + + public static void main(String[] args) { + ArrayUtil arrayUtil = new ArrayUtil(); + System.out.println("-------------------------"); + } +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/download/DownloadThread.java b/group05/578505552/src/main/java/dataStruct/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..c837e08f8b --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/download/DownloadThread.java @@ -0,0 +1,47 @@ +package dataStruct.com.coderising.download; + +import dataStruct.com.coderising.download.api.Connection; +import dataStruct.com.coderising.download.api.DownloadListener; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + File targetFile; + DownloadListener listener; + + public DownloadThread(Connection conn, int startPos, int endPos, File targetFile, DownloadListener listener){ + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.targetFile = targetFile; + this.listener = listener; + } + public void run(){ + try { + System.out.println("线程" + this.getName() + "正在下载" + startPos + "--" + endPos + "的数据"); + + byte[] content = conn.read(startPos, endPos); + RandomAccessFile randomAccessFile = new RandomAccessFile(targetFile, "rw"); + randomAccessFile.seek(startPos); + randomAccessFile.write(content, 0, endPos - startPos + 1); + randomAccessFile.close(); + + System.out.println("线程" + this.getName() + "完成" + startPos + "--" + endPos + "数据的下载"); + + if (FileDownloader.isDownLoadFinished()){ + listener.notifyFinished(); + System.out.println(">>>>>>>>>>>>>>线程" + this.getName() + "完成了最终的下载"); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + conn.close(); + } + } +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/download/FileDownloader.java b/group05/578505552/src/main/java/dataStruct/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..324ba4d29d --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/download/FileDownloader.java @@ -0,0 +1,66 @@ +package dataStruct.com.coderising.download; + +import dataStruct.com.coderising.download.api.Connection; +import dataStruct.com.coderising.download.api.ConnectionException; +import dataStruct.com.coderising.download.api.ConnectionManager; +import dataStruct.com.coderising.download.api.DownloadListener; + +import java.io.File; + +public class FileDownloader { + + String url; + DownloadListener listener; + ConnectionManager cm; + public static final int threadCount = 5; + private static int threadFinished; + + public FileDownloader(String _url) { + this.url = _url; + } + + public void execute(){ + try { + Connection conn = cm.open(this.url); + int length = conn.getContentLength(); + + File targetFile = new File("D:" + File.separator + getFileName()); + System.out.println("总长度:" + length); + + int temp = length / threadCount; + for (int i = 0; i < threadCount; i++) { + int startPos = i * temp; + int endPos = startPos + temp - 1; + if (i == threadCount - 1){ + endPos = length; + } + String threadName = "DownloadThread" + String.valueOf(i); + Connection connection = cm.open(url); + DownloadThread downloadThread = new DownloadThread(connection, startPos, endPos, targetFile, listener); + downloadThread.setName(threadName); + downloadThread.start(); + } + } catch (ConnectionException e) { + e.printStackTrace(); + } finally{ + + } + } + + public String getFileName(){ + return "meinv.jpg"; + } + + public synchronized static boolean isDownLoadFinished(){ + threadFinished++; + return threadFinished == threadCount; + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/Connection.java b/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..da33f7360c --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/Connection.java @@ -0,0 +1,23 @@ +package dataStruct.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/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/ConnectionException.java b/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..2efc59eec6 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,20 @@ +package dataStruct.com.coderising.download.api; + +public class ConnectionException extends Exception { + + public ConnectionException() { + } + + public ConnectionException(String message) { + super(message); + } + + public ConnectionException(String message, Throwable cause) { + super(message, cause); + } + + public ConnectionException(Throwable cause) { + super(cause); + } + +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/ConnectionManager.java b/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..2ac9aa5ac9 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package dataStruct.com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/DownloadListener.java b/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..8daca6846c --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package dataStruct.com.coderising.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/download/impl/ConnectionImpl.java b/group05/578505552/src/main/java/dataStruct/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..c9b1c7c103 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,49 @@ +package dataStruct.com.coderising.download.impl; + +import dataStruct.com.coderising.download.api.Connection; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +public class ConnectionImpl implements Connection{ + + private HttpURLConnection conn; + + public ConnectionImpl(HttpURLConnection urlConnection) { + this.conn = urlConnection; + } + + public byte[] read(int startPos, int endPos) throws IOException { + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + if (conn.getResponseCode() == 206){ + InputStream inputStream = conn.getInputStream(); + byte[] temp = new byte[endPos - startPos + 1]; + while ((inputStream.read(temp)) != -1){ + + } + return temp; + } + return new byte[0]; + } + + public int getContentLength() { + try { + if (conn.getResponseCode() == 200){ + return conn.getContentLength(); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + this.close(); + } + return 0; + } + + public void close() { + if (conn != null){ + conn.disconnect(); + conn = null; + } + } +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/download/impl/ConnectionManagerImpl.java b/group05/578505552/src/main/java/dataStruct/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..e8e5a85aeb --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,25 @@ +package dataStruct.com.coderising.download.impl; + +import dataStruct.com.coderising.download.api.Connection; +import dataStruct.com.coderising.download.api.ConnectionException; +import dataStruct.com.coderising.download.api.ConnectionManager; + +import java.net.HttpURLConnection; +import java.net.URL; + +public class ConnectionManagerImpl implements ConnectionManager { + + public Connection open(String url) throws ConnectionException { + + try { + URL urlObject = new URL(url); + HttpURLConnection urlConnection = (HttpURLConnection)urlObject.openConnection(); + urlConnection.setRequestMethod("GET"); + urlConnection.setReadTimeout(5000); + return new ConnectionImpl(urlConnection); + } catch (java.io.IOException e) { + throw new ConnectionException("连接失败"); + } + } + +} diff --git a/group05/578505552/src/main/java/com/coderising/litestruts/Action.java b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/Action.java similarity index 89% rename from group05/578505552/src/main/java/com/coderising/litestruts/Action.java rename to group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/Action.java index 743f452030..1c9ad259ad 100644 --- a/group05/578505552/src/main/java/com/coderising/litestruts/Action.java +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/Action.java @@ -1,38 +1,38 @@ -package com.coderising.litestruts; - - -import java.util.Map; - -/** - * Created by songbao.yang on 2017/3/1. - * - */ -public class Action { - private String name; - private String className; - private Map results; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getClassName() { - return className; - } - - public void setClassName(String className) { - this.className = className; - } - - public Map getResults() { - return results; - } - - public void setResults(Map results) { - this.results = results; - } -} +package dataStruct.com.coderising.litestruts; + + +import java.util.Map; + +/** + * Created by songbao.yang on 2017/3/1. + * + */ +public class Action { + private String name; + private String className; + private Map results; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public Map getResults() { + return results; + } + + public void setResults(Map results) { + this.results = results; + } +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/Configuration.java b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/Configuration.java new file mode 100644 index 0000000000..c85b40029f --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/Configuration.java @@ -0,0 +1,7 @@ +package dataStruct.com.coderising.litestruts; + +/** + * Created by songbao.yang on 2017/3/10. + */ +public class Configuration { +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/LoginAction.java b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..b7789abf28 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/LoginAction.java @@ -0,0 +1,38 @@ +package dataStruct.com.coderising.litestruts; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * + */ +public class LoginAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group05/578505552/src/main/java/com/coderising/litestruts/ReflectUtils.java b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/ReflectUtils.java similarity index 81% rename from group05/578505552/src/main/java/com/coderising/litestruts/ReflectUtils.java rename to group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/ReflectUtils.java index c11c5632f3..cb35e59963 100644 --- a/group05/578505552/src/main/java/com/coderising/litestruts/ReflectUtils.java +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/ReflectUtils.java @@ -1,4 +1,4 @@ -package com.coderising.litestruts; +package dataStruct.com.coderising.litestruts; import java.lang.reflect.Method; diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/Struts.java b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..00bc5a446f --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/Struts.java @@ -0,0 +1,131 @@ +package dataStruct.com.coderising.litestruts; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class Struts { + + public static View runAction(String actionName, Map parameters) { + +// 0. 读取配置文件struts.xml + Action action = matchAction(parseXml("/struts.xml"), actionName); + try { + +// 1. 根据actionName找到相对应的class, 通过反射实例化(创建对象), +// 根据parameters中的数据,调用对象的setter方法 + Class clazz = Class.forName(action.getClassName()); + Object instance = clazz.newInstance(); + for (String key : parameters.keySet()){ + try { + PropertyDescriptor propertyDescriptor = new PropertyDescriptor(key, clazz); + Method setMethod = propertyDescriptor.getWriteMethod(); + setMethod.invoke(instance, parameters.get(key)); + } catch (IntrospectionException e) { + e.printStackTrace(); + } + } + +// 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + Method exectueMethod = null; + String result = null; + try { + exectueMethod = clazz.getMethod("execute"); + result = (String)exectueMethod.invoke(instance); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + +// 3. 通过反射找到对象的所有getter方法(例如 getMessage), +// 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , +// 放到View对象的parameters + Map hashMap = new HashMap(); + Field[] declaredFields = clazz.getDeclaredFields(); + for (Field field : declaredFields){ + String name = field.getName(); + try { + PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, clazz); + Method getMethod = propertyDescriptor.getReadMethod(); + Object res = getMethod.invoke(instance); + hashMap.put(name, res); + } catch (IntrospectionException e) { + e.printStackTrace(); + } + } + +// 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, +// 放到View对象的jsp字段中。 + View view = new View(); + view.setJsp((String)action.getResults().get(result)); + view.setParameters(hashMap); + return view; + + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + return null; + } + + private static Element parseXml(String resourcePath){ + + InputStream resourceAsStream = Struts.class.getResourceAsStream(resourcePath); + SAXReader saxReader = new SAXReader(); + try { + Document document = saxReader.read(resourceAsStream); + Element rootElement = document.getRootElement(); + return rootElement; + } catch (DocumentException e) { + e.printStackTrace(); + } + + throw new RuntimeException("fail to parse xml"); + } + + private static Action matchAction(Element rootElement, String actionName){ + + List actions = rootElement.elements("action"); + Iterator iterator = actions.iterator(); + Action action = new Action(); + while (iterator.hasNext()){ + Element actionElement = (Element) iterator.next(); + String nameAttributeValue = actionElement.attributeValue("name"); + if (actionName.equals(nameAttributeValue)){ + action.setName(nameAttributeValue); + action.setClassName(actionElement.attributeValue("class")); + List results = actionElement.elements("result"); + Map resultMap = new HashMap(); + Iterator it = results.iterator(); + while (it.hasNext()){ + Element resultElement = (Element)it.next(); + resultMap.put(resultElement.attributeValue("name"), (String)resultElement.getData()); + } + action.setResults(resultMap); + } + } + + return action; + } + + + + +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/View.java b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..bb6f39e9a9 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coderising/litestruts/View.java @@ -0,0 +1,23 @@ +package dataStruct.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/group05/578505552/src/main/java/dataStruct/com/coding/basic/ArrayList.java b/group05/578505552/src/main/java/dataStruct/com/coding/basic/ArrayList.java new file mode 100644 index 0000000000..cdbb1107a0 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coding/basic/ArrayList.java @@ -0,0 +1,103 @@ +package dataStruct.com.coding.basic; + +import java.util.NoSuchElementException; + +/** + * Created by songbao.yang on 2017/2/21. + * + */ +public class ArrayList implements List { + + private int size = 0; + private Object[] elementData; + private static final int MIN_CAPACITY = 10; + + public ArrayList(int size) { + if (size < 0){ + throw new IllegalArgumentException("illega size: " + size); + } + this.elementData = new Object[size]; + } + + public ArrayList() { + this.elementData = new Object[0]; + } + + public void add(T o){ + ensureCapacity(size + 1); + elementData[size++] = o; + } + + private void ensureCapacity(int minCapacity){ + if (minCapacity < 0 ){ + throw new OutOfMemoryError(); + } + + int newCapcity = size; + if(minCapacity < MIN_CAPACITY){ + newCapcity = MIN_CAPACITY; + } else if(minCapacity > elementData.length){ + int tmp = elementData.length << 1; + newCapcity = tmp > elementData.length ? tmp : Integer.MAX_VALUE; + } + + newCapcity = minCapacity; + Object[] newData = new Object[newCapcity]; + System.arraycopy(elementData, 0, newData, 0, size); + elementData = newData; + } + + public void add(int index, T o){ + indexCheck(index); + ensureCapacity(size+1); + System.arraycopy(elementData, index, elementData, index+1, size-index); + elementData[index] = o; + size++; + } + + public T get(int index){ + indexCheck(index); + return (T) elementData[index]; + } + + private void indexCheck(int index){ + if(index < 0){ + throw new IllegalArgumentException("illegal index: " + index); + } + if(index >= size){ + throw new IndexOutOfBoundsException(); + } + } + + public T remove(int index){ + indexCheck(index); + Object rm = elementData[index]; + System.arraycopy(elementData, index+1, elementData, index, size-index-1); + size--; + return (T) rm; + } + + public int size(){ + return size; + } + + public Iterator iterator(){ + return new Itr(); + } + + //静态内部类的访问权限不同有何区别?? + private class Itr implements Iterator { + private int cursor = 0; + + public boolean hasNext() { + return cursor != size; + } + + public Object next() { + if (hasNext()){ + return elementData[cursor++]; + } + throw new NoSuchElementException(); + } + } +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coding/basic/BinaryTreeNode.java b/group05/578505552/src/main/java/dataStruct/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..ee0351da07 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coding/basic/BinaryTreeNode.java @@ -0,0 +1,60 @@ +package dataStruct.com.coding.basic; + +/** + * Created by songbao.yang on 2017/2/21. + * + */ +public class BinaryTreeNode { + + private Integer data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public Object getData() { + return data; + } + public void setData(Integer 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(Integer o){ + if (o == null){ + throw new IllegalArgumentException("can not insert null"); + } + + BinaryTreeNode newNode = new BinaryTreeNode(); + newNode.data = o; + newNode.left = null; + newNode.right = null; + + BinaryTreeNode cursor = this; + BinaryTreeNode pre = cursor; + while (cursor != null){ + pre = cursor; + if (o.compareTo(cursor.data) < 0){ + cursor = cursor.left; + } else { + cursor = cursor.right; + } + } + + if (o.compareTo(pre.data) < 0){ + pre.left = newNode; + } else { + pre.right = newNode; + } + return this; + } +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coding/basic/Iterator.java b/group05/578505552/src/main/java/dataStruct/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..1755e82202 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coding/basic/Iterator.java @@ -0,0 +1,11 @@ +package dataStruct.com.coding.basic; + +/** + * Created by songbao.yang on 2017/2/21. + * + */ +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coding/basic/LinkedList.java b/group05/578505552/src/main/java/dataStruct/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..9238a5c7a0 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coding/basic/LinkedList.java @@ -0,0 +1,390 @@ +package dataStruct.com.coding.basic; + +import java.util.NoSuchElementException; + +/** + * Created by songbao.yang on 2017/2/21. + * + */ +public class LinkedList implements List { + + private Node head; + private int elementCount; + + //head作为一个节点,其next的值指向List中真正的第一个节点 + public LinkedList() { + head = new Node(); + head.next = null; + head.data = null; + elementCount = 0; + } + + public void add(T o){ + Node newNode = new Node(); + newNode.data = o; + newNode.next = null; + + Node cursor = head; + while (cursor.next != null){ + cursor = cursor.next; + } + cursor.next = newNode; + elementCount++; + } + + + public void add(int index , T o){ + indexRangeCheck(index); + Node newNode = new Node(); + newNode.data = o; + + Node cursor = head; + for (int i = 0; i < index; i++) { + cursor = cursor.next; //将cursor移动到index-1节点处; + } + + newNode.next = cursor.next; //将新节点指向原index处的节点 + cursor.next = newNode;//将原index-1处的节点指向新节点 + elementCount++; + } + + private void indexRangeCheck(int index){ + if (index < 0 || index >= size()){ + throw new IndexOutOfBoundsException(); + } + } + + public T get(int index){ + indexRangeCheck(index); + Node cursor = head; + for (int i = 0; i < index; i++) { + cursor = cursor.next; + } + return (T) cursor.next.data; + } + + public T remove(int index){ + indexRangeCheck(index); + Node cursor = head; + for (int i = 0; i < index; i++) { + cursor = cursor.next; + } + Node indexNode = cursor.next; + cursor.next = indexNode.next; + elementCount--; + return (T) indexNode; + } + + public int size(){ + return elementCount; + } + + public void addFirst(T o){ + Node node = new Node(); + node.data = o; + node.next = head.next; + head.next = node; + elementCount++; + } + + public void addLast(T o){ + + Node cursor = head; + while (cursor.next != null){ + cursor = cursor.next; + } + Node newNode = new Node(); + newNode.data = o; + newNode.next = null; + cursor.next = newNode; + elementCount++; + } + + public T removeFirst(){ + + if (size() == 0){ + throw new RuntimeException("no element in list"); + } + Node firstNode = head.next; + head.next = head.next.next; + elementCount--; + return (T) firstNode; + } + + public T removeLast(){ + if (size() == 0){ + throw new RuntimeException("no element in list"); + } + + Node cursor = head; + for (int i = 0; i < size() - 1; i++) { + cursor = cursor.next; + } + + Node lastNode = cursor.next; + cursor.next = null; + elementCount--; + + return (T) lastNode; + } + + public Iterator iterator(){ + return new Itr(); + } + + private class Itr implements Iterator { + + private Node itrCursor = head; + + public boolean hasNext() { + + return itrCursor.next != null; + } + + public Object next() { + if (hasNext()){ + return itrCursor.next; + } + throw new NoSuchElementException(); + } + } + + private static class Node{ + T data; + Node next; + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if (elementCount <= 1){ + return; + } + + Node first = head.next; + Node second = head.next.next; + + first.next = null; + while (second != null){ + Node temp = second.next; + second.next = first; + first = second; + second = temp; + } + head.next = first; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + + Node cousor = head.next; + for (int i = 0; i < elementCount / 2; i++) { + Node temp = cousor; + cousor = cousor.next; + temp.data = null; + temp.next = null; + } + head.next = cousor; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if (i < 0 || length < 0){ + return; + } + if (i > elementCount - 1){ + throw new IndexOutOfBoundsException("index i is too big"); + } + + Node beforei = head; + for (int j = 0; j < i; j++) { + beforei = beforei.next; + } + Node cursor = beforei.next; + for (int j = 0; j < length; j++) { + if (cursor != null){ + Node temp = cursor; + cursor = cursor.next; + temp.data = null; + temp.next = null; + }else { + break; + } + } + beforei.next = cursor; + } + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + + int[] result = new int[list.size()]; + int i = 0; + int pre = 0; + Node cousor = head.next; + Iterator YIterator = list.iterator(); + while (YIterator.hasNext()){ + int index = (Integer) YIterator.next(); + if (index > elementCount - 1){ + break; + } + moveForwardNIndex(cousor, index - pre); + result[i++] = (Integer) cousor.data; + pre = index; + } + + int[] ints = new int[result.length]; + System.arraycopy(result, 0, ints, 0, result.length); + return ints; + } + + private void moveForwardNIndex(Node index, int n){ + for (int i = 0; i < n; i++) { + if (index == null){ + break; + } + index = index.next; + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + + Node pre = head; + Node node = head.next; + while (node != null){ + if (list.contains(node.data)){ + pre.next = node.next; + node = node.next; + } else { + pre = node; + node = node.next; + } + } + } + + public boolean contains(T data){ + + Node cursor = this.head.next; + while (cursor != null){ + if (cursor.data.equals(data)){ + return true; + } + } + return false; + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + + if (elementCount <= 1){ + return; + } + Node pre = head.next; + Node node = pre.next; + while (node != null){ + if (node.data.equals(pre.data)){ + pre.next = node.next; + node = node.next; + } else { + pre = node; + node = node.next; + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + //TODO 这个泛型的比较没搞明白, 为什么会出现cast的问题,不应该都是T类型吗 + public void removeRange(T min, T max){ + if (min.compareTo(max) > 0){ + return; + } + if (size() == 0){ + return; + } + Node beforeMin = head; + //泛型化 + while (beforeMin.next != null && beforeMin.next.data.compareTo(min) <= 0){ + beforeMin = beforeMin.next; + } + Node afterMax = beforeMin.next; + while (afterMax != null && afterMax.data.compareTo(max) < 0){ + afterMax = afterMax.next; + } + beforeMin.next = afterMax; + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection(LinkedList list){ + + if (list == null || list.size() == 0 || this.size() == 0){ + return new LinkedList(); + } + + Node cursorA = this.head.next; + Node cursorB = list.head.next; + LinkedList listC = new LinkedList(); + + while (cursorA != null && cursorB != null){ + if (cursorA.data.compareTo(cursorB.data) == 0){ + listC.add((T)cursorA.data); + } else if (cursorA.data.compareTo(cursorB.data) < 0){ + cursorA = cursorA.next; + } else { + cursorB = cursorB.next; + } + } + return listC; + } + + public void addAfter(Node node, T o){ + if (node == null){ + return; + } + Node newNode = new Node(); + newNode.data = o; + addAfter(node, newNode); + } + + public void addAfter(Node node, Node newNode){ + if (node == null || newNode == null){ + return; + } + newNode.next = node.next; + node.next = newNode; + } +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coding/basic/List.java b/group05/578505552/src/main/java/dataStruct/com/coding/basic/List.java new file mode 100644 index 0000000000..20d7a6daf9 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coding/basic/List.java @@ -0,0 +1,14 @@ +package dataStruct.com.coding.basic; + +/** + * Created by songbao.yang on 2017/2/21. + * + */ +public interface List { + public void add(T o); + public void add(int index, T o); + public T get(int index); + public T remove(int index); + public int size(); + public Iterator iterator(); +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coding/basic/Queue.java b/group05/578505552/src/main/java/dataStruct/com/coding/basic/Queue.java new file mode 100644 index 0000000000..2b3a62a5d3 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coding/basic/Queue.java @@ -0,0 +1,90 @@ +package dataStruct.com.coding.basic; + +import java.util.NoSuchElementException; + +/** + * Created by songbao.yang on 2017/2/22. + * + */ +public class Queue { + + private Object[] elementData; + private int head; //对头的位置 + private int tail; //队尾的位置 + private int size; //队列中元素的个数 + private static final int MIN_INITIAL_CAPACITY = 10; + + public Queue() { + this.elementData = new Object[MIN_INITIAL_CAPACITY]; + this.head = 0; + this.tail = 0; + this.size = 0; + } + + public Queue(int initCapcacity) { + if (initCapcacity < MIN_INITIAL_CAPACITY){ + initCapcacity = MIN_INITIAL_CAPACITY; + } + this.elementData = new Object[initCapcacity]; + this.head = 0; + this.tail = 0; + this.size = 0; + } + + public void enQueue(Object o){ + ensureCapacity(size+1); + if(size != 0){ + tail++; + } + if(tail == elementData.length){ + tail = 0; + } + elementData[tail] = o; + size++; + } + + private void ensureCapacity(int minCapcacity){ + if(minCapcacity <= elementData.length){ + return; + } + + int newCapcacity = elementData.length << 1; + if (newCapcacity < elementData.length){ + newCapcacity = Integer.MAX_VALUE; + } + + Object[] newData = new Object[newCapcacity]; + if(size != 0){ + if(tail >= head){ + System.arraycopy(elementData, head, newData, 0, size); + } else { + System.arraycopy(elementData, head, newData, 0, elementData.length - head); + System.arraycopy(elementData, 0, newData, elementData.length - head, tail + 1); + } + elementData = newData; + head = 0; + tail = this.size - 1; + } + } + + public Object deQueue(){ + if (isEmpty()){ + throw new NoSuchElementException("empty queue"); + } + Object ele = elementData[head]; + size--; + head++; + if(head == elementData.length){ + head = 0; + } + return ele; + } + + public boolean isEmpty(){ + return size == 0; + } + + public int size(){ + return size; + } +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coding/basic/Stack.java b/group05/578505552/src/main/java/dataStruct/com/coding/basic/Stack.java new file mode 100644 index 0000000000..4f41c69a9e --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coding/basic/Stack.java @@ -0,0 +1,63 @@ +package dataStruct.com.coding.basic; + + +import java.util.EmptyStackException; + +/** + * Created by songbao.yang on 2017/2/22. + * + */ +public class Stack { + + private Object[] elementData; + private static final int MIN_INITIAL_CAPACITY = 10; + private int cursor; + + public Stack() { + elementData = new Object[MIN_INITIAL_CAPACITY]; + cursor = -1; + } + + public void push(Object o){ + ensureCapacity(size() + 1); + cursor++; + elementData[cursor] = o; + } + + private void ensureCapacity(int minCapacity){ + if(minCapacity <= elementData.length){ + return; + } + + int newSize = elementData.length << 1; + if (newSize < elementData.length){ + newSize = Integer.MAX_VALUE; + } + + Object[] newDataArray = new Object[newSize]; + System.arraycopy(elementData, 0, newDataArray, 0, size()); + elementData = newDataArray; + } + + + public Object pop(){ + Object ele = peek(); + cursor--; + return ele; + } + + public Object peek(){ + if (isEmpty()){ + throw new EmptyStackException(); + } + return elementData[cursor]; + } + + public boolean isEmpty(){ + return size() == 0; + } + + public int size(){ + return cursor + 1; + } +} diff --git a/group05/578505552/src/main/java/dataStruct/com/coding/basic/linklist/LRUPageFrame.java b/group05/578505552/src/main/java/dataStruct/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..cebc4bc739 --- /dev/null +++ b/group05/578505552/src/main/java/dataStruct/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,105 @@ +package dataStruct.com.coding.basic.linklist; + +/** + * 用双向链表实现LRU算法 + * @author songbao.yang + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + } + + private int capacity; + private int size; + + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + this.size = 0; + first = null; + last = null; + } + + /** + * 获取缓存中对象 + * + * @param pageNum + * @return + */ + public void access(int pageNum) { + + Node newNode = new Node(); + newNode.pageNum = pageNum; + + //往链表头部加入元素 + if (size == 0){ + first = newNode; + last = newNode; + } else { + newNode.next = first; + if (first == null){ + System.out.println("fuck"); + } + first.prev = newNode; + first = newNode; + } + size++; + + //去重 + Node node = first.next; + while (node != null){ + if (node.pageNum == pageNum){ + node.prev.next = node.next; + + if (node == last){ + last = node.prev; + } else { + node.next.prev = node.prev; + } + + Node tmp = node; + node = node.next; + tmp.next = null; + tmp.prev = null; + size--; + } else { + node = node.next; + } + } + + //调整容量 + if (size > capacity){ + last = last.prev; + last.next.prev = null; + last.next = null; + size--; + } + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group05/578505552/src/main/java/miniJvm/com/coderising/jvm/loader/ClassFileLoader.java b/group05/578505552/src/main/java/miniJvm/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..97dc361c12 --- /dev/null +++ b/group05/578505552/src/main/java/miniJvm/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,68 @@ +package miniJvm.com.coderising.jvm.loader; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + String fullClassName = className.replace(".", "\\") + ".class"; + for (String clzpath : clzPaths){ + byte[] binaryCode = readBinaryCode(clzpath, fullClassName); + if (binaryCode != null){ + return binaryCode; + } + } + return null; + } + + private byte[] readBinaryCode(String clzPath, String fullClassName){ + + String filePath = clzPath + "\\" + fullClassName; + File classFile = new File(filePath); + if (!classFile.exists()){ + return null; + } + try { + FileInputStream fileInputStream = new FileInputStream(classFile); + DataInputStream dataInputStream = new DataInputStream(fileInputStream); + List bytes = new ArrayList(); + int b; + while ((b = dataInputStream.read()) != -1){ + bytes.add((byte)b); + } + byte[] res = new byte[bytes.size()]; + for (int i = 0; i < bytes.size(); i++){ + res[i] = bytes.get(i); + } + return res; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public void addClassPath(String path) { + + if (path == null){ + return; + } + clzPaths.add(path); + } + + public String getClassPath(){ + + StringBuffer stringBuffer = new StringBuffer(); + for (String path : clzPaths){ + stringBuffer.append(path).append(";"); + } + return stringBuffer.substring(0, stringBuffer.length() - 1); + } + +} diff --git a/group05/578505552/src/main/java/miniJvm/com/coderising/jvm/loader/EmployeeV1.java b/group05/578505552/src/main/java/miniJvm/com/coderising/jvm/loader/EmployeeV1.java new file mode 100644 index 0000000000..edae33a2aa --- /dev/null +++ b/group05/578505552/src/main/java/miniJvm/com/coderising/jvm/loader/EmployeeV1.java @@ -0,0 +1,31 @@ +package miniJvm.com.coderising.jvm.loader; + +public class EmployeeV1 { + + + private String name; + private int age; + + public EmployeeV1() { + } + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + public void setAge(int age){ + this.age = age; + } + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + public static void main(String[] args){ + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group05/578505552/src/main/resources/struts.xml b/group05/578505552/src/main/resources/struts.xml index 0a44e0927e..0dc7b6de98 100644 --- a/group05/578505552/src/main/resources/struts.xml +++ b/group05/578505552/src/main/resources/struts.xml @@ -1,6 +1,6 @@ - + /jsp/homepage.jsp /jsp/showLogin.jsp diff --git a/group05/578505552/src/test/java/com/coderising/array/ArrayUtilTest.java b/group05/578505552/src/test/java/com/coderising/array/ArrayUtilTest.java deleted file mode 100644 index 607f4fed5b..0000000000 --- a/group05/578505552/src/test/java/com/coderising/array/ArrayUtilTest.java +++ /dev/null @@ -1,206 +0,0 @@ -package com.coderising.array; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; - -/** - * Created by songbao.yang on 2017/3/2. - * - */ -public class ArrayUtilTest { - - private ArrayUtil arrayUtil; - - @Before - public void setUp() throws Exception { - arrayUtil = new ArrayUtil(); - } - - @After - public void tearDown() throws Exception { - - } - - @Test - public void reverseArray() throws Exception { - - int[][] actualAndExpected = { - {}, {}, {0}, {0}, - {1,2,3,4,5,6}, {6,5,4,3,2,1}, - {7,9,30,3,4}, {4,3,30,9,7} - }; - - for (int i = 0; i < actualAndExpected.length; i += 2) { - int[] acutal = actualAndExpected[i]; - int[] expected = actualAndExpected[i+1]; - arrayUtil.reverseArray(acutal); - Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, acutal)); - } - } - - @Test - public void removeZero() throws Exception { - int[][] actualAndExpected = { - {}, {}, {0}, {}, - {1,0,3,0,5,0}, {1,3,5}, - {1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}, {1,3,4,5,6,6,5,4,7,6,7,5} - }; - - for (int i = 0; i < actualAndExpected.length; i += 2) { - int[] acutal = actualAndExpected[i]; - int[] expected = actualAndExpected[i+1]; - int[] ints = arrayUtil.removeZero(acutal); - Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, ints)); - } - } - - @Test - public void merge() throws Exception { - int[][] actualAndExpected = { - {}, {}, {}, - {}, {0}, {0}, - {3,5,7,8}, {4,5,6,7},{3,4,5,6,7,8}, - {1,2,3,4,5,}, {6,7,8,9,10}, {1,2,3,4,5,6,7,8,9,10} - }; - - for (int i = 0; i < actualAndExpected.length; i += 3) { - int[] array1 = actualAndExpected[i]; - int[] array2 = actualAndExpected[i+1]; - int[] expected = actualAndExpected[i+2]; - int[] result = arrayUtil.merge(array1, array2); - Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, result)); - } - - } - - @Test - public void grow() throws Exception { - int[][] actualAndExpected = { - {}, {}, - {1}, {}, - {5}, {0,0,0,0,0}, - {0},{2,3,6}, - {3}, {2,3,6,0,0,0} - }; - - for (int i = 0; i < actualAndExpected.length; i += 3) { - int[] oldArray = actualAndExpected[i]; - int size = actualAndExpected[i+1][0]; - int[] expected = actualAndExpected[i+2]; - int[] newArray = arrayUtil.grow(oldArray, size); - Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, newArray)); - } - } - - @Test - public void fibonacci() throws Exception { - int[][] actualAndExpected = { - {0}, {}, - {1}, {}, - {2}, {1,1}, - {3}, {1,1,2}, - {4}, {1,1,2,3}, - {15}, {1,1,2,3,5,8,13}, - }; - - for (int i = 0; i < actualAndExpected.length; i += 2) { - int max = actualAndExpected[i][0]; - int[] expected = actualAndExpected[i+1]; - int[] actual = arrayUtil.fibonacci(max); - Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, actual)); - } - } - - @Test - public void getPrimes() throws Exception { - int[][] actualAndExpected = { - {-1}, {}, - {0}, {}, - {1}, {}, - {2}, {}, - {3}, {2}, - {4}, {2,3}, - {23}, {2,3,5,7,11,13,17,19}, - }; - - for (int i = 0; i < actualAndExpected.length; i += 2) { - int max = actualAndExpected[i][0]; - int[] expected = actualAndExpected[i+1]; - int[] actual = arrayUtil.getPrimes(max); - Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, actual)); - } - } - - @Test - public void getPerfectNumbers() throws Exception { - int[][] actualAndExpected = { - {-1}, {}, - {0}, {}, - {1}, {}, - {2}, {}, - {7}, {6}, - {30}, {6,28}, - {500}, {6,28,496}, - {10000}, {6,28,496,8128} - }; - - for (int i = 0; i < actualAndExpected.length; i += 2) { - int max = actualAndExpected[i][0]; - int[] expected = actualAndExpected[i+1]; - int[] actual = arrayUtil.getPerfectNumbers(max); - Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, actual)); - } - } - - @Test - public void join() throws Exception { - int[][] arrays = { - {}, - {3,8,9}, - {1}, - {0,0,0,0,0}, - {1,2,3,4,5} - }; - String[] separators = {"", "-", "+", "*", "00"}; - String[] expecteds = { - "", - "3-8-9", - "1", - "0*0*0*0*0", - "1002003004005" - }; - for (int i = 0; i < arrays.length; i++) { - int[] array = arrays[i]; - String separator = separators[i]; - String expected = expecteds[i]; - String actual = arrayUtil.join(array, separator); - Assert.assertTrue("wrong index: " + String.valueOf(i), expected.equals(actual)); - } - } - - private boolean isArrayEqual(int[] expected, int[] actual){ - if (expected.length != actual.length){ - System.out.println("expected.length != actual.length"); - System.out.println("expected: " + Arrays.toString(expected)); - System.out.println("actual: " + Arrays.toString(actual)); - return false; - } - - for (int i = 0; i < expected.length; i++) { - if (expected[i] != actual[i]){ - System.out.println("expected[i] != actual[i]"); - System.out.println("expected: " + Arrays.toString(expected)); - System.out.println("actual: " + Arrays.toString(actual)); - return false; - } - } - - return true; - } - -} \ No newline at end of file diff --git a/group05/578505552/src/test/java/com/coderising/litestruts/StrutsTest.java b/group05/578505552/src/test/java/com/coderising/litestruts/StrutsTest.java deleted file mode 100644 index 6df05450b6..0000000000 --- a/group05/578505552/src/test/java/com/coderising/litestruts/StrutsTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.coderising.litestruts; - -import org.junit.Assert; -import org.junit.Test; - -import java.util.HashMap; -import java.util.Map; - - -public class StrutsTest { - - @Test - public void testLoginActionSuccess() { - - String actionName = "login"; - - Map params = new HashMap(); - params.put("name","test"); - params.put("password","1234"); - - - View view = Struts.runAction(actionName,params); - - Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); - Assert.assertEquals("login successful", view.getParameters().get("message")); - } - - @Test - public void testLoginActionFailed() { - String actionName = "login"; - Map params = new HashMap(); - params.put("name","test"); - params.put("password","123456"); //密码和预设的不一致 - - View view = Struts.runAction(actionName,params); - - Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); - Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); - } -} diff --git a/group05/578505552/src/test/java/com/coding/basic/BinaryTreeNodeTest.java b/group05/578505552/src/test/java/com/coding/basic/BinaryTreeNodeTest.java deleted file mode 100644 index d1e408554e..0000000000 --- a/group05/578505552/src/test/java/com/coding/basic/BinaryTreeNodeTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.coding.basic; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Created by songbao.yang on 2017/2/28. - * - */ -public class BinaryTreeNodeTest { - - private BinaryTreeNode node; - - @Before - public void setUp() throws Exception { - node = new BinaryTreeNode(); - node.setData(100); - node.setLeft(null); - node.setRight(null); - } - - @After - public void tearDown() throws Exception { - - } - - @Test - public void insert() throws Exception { - - for (int i = 0; i < 100; i++) { - int ele = (int)Math.floor(Math.random() * 200); - node.insert(ele); - } - } -} \ No newline at end of file diff --git a/group05/578505552/src/test/java/com/coding/basic/QueueTest.java b/group05/578505552/src/test/java/com/coding/basic/QueueTest.java deleted file mode 100644 index 905054670d..0000000000 --- a/group05/578505552/src/test/java/com/coding/basic/QueueTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.coding.basic; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Created by songbao.yang on 2017/2/24. - */ -public class QueueTest { - - private static final int SIZE = 2000; - private Queue queue; - - @Before - public void setUp() throws Exception { - queue = new Queue(); - } - - @After - public void tearDown() throws Exception { - - } - - @Test - public void enQueue() throws Exception { - for (int i = 0; i < SIZE; i++) { - queue.enQueue(i); - Assert.assertEquals(i+1, queue.size()); - } - } - - @Test - public void deQueue1() throws Exception { - enQueue(); - - int i = 0; - int startSize = queue.size(); - while (!queue.isEmpty()) { - Assert.assertEquals(startSize - i, queue.size()); - Object o = queue.deQueue(); - Assert.assertEquals(SIZE - i - 1, queue.size()); - Assert.assertEquals(i, o); - i++; - } - } - - @Test - public void deQueue2() throws Exception { - enQueue(); - int startSize = queue.size(); - - for (int i = 0; i < startSize; i++) { - queue.deQueue(); - Assert.assertEquals(startSize - 1, queue.size()); - queue.enQueue(i+1000); - Assert.assertEquals(startSize, queue.size()); - } - - } - - @Test - public void isEmpty() throws Exception { - - } - - @Test - public void size() throws Exception { - - } - -} \ No newline at end of file diff --git a/group05/578505552/src/test/java/com/coding/basic/StackTest.java b/group05/578505552/src/test/java/com/coding/basic/StackTest.java deleted file mode 100644 index b65d446c97..0000000000 --- a/group05/578505552/src/test/java/com/coding/basic/StackTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.coding.basic; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Created by songbao.yang on 2017/2/24. - * - */ -public class StackTest { - - private Stack stack; - - public static final int SIZE = 100; - - @Before - public void setUp() throws Exception { - stack = new Stack(); - } - - @After - public void tearDown() throws Exception { - - } - - @Test - public void push() throws Exception { - for (int i = 0; i < SIZE; i++) { - stack.push(i); - Assert.assertEquals(i+1, stack.size()); - } - System.out.println(); - } - - @Test - public void pop() throws Exception { - push(); - int beginSize = stack.size(); - for (int i = 0; i < beginSize; i++) { - Object ele = stack.pop(); - Assert.assertEquals(beginSize-i-1, stack.size()); - Assert.assertEquals(beginSize-i-1, ele); - } - } - - @Test - public void peek() throws Exception { - - } - - @Test - public void isEmpty() throws Exception { - - } - - @Test - public void size() throws Exception { - - } - -} \ No newline at end of file diff --git a/group05/578505552/src/test/java/dataStruct/com/coderising/array/ArrayUtilTest.java b/group05/578505552/src/test/java/dataStruct/com/coderising/array/ArrayUtilTest.java new file mode 100644 index 0000000000..b09f2efcd0 --- /dev/null +++ b/group05/578505552/src/test/java/dataStruct/com/coderising/array/ArrayUtilTest.java @@ -0,0 +1,205 @@ +package dataStruct.com.coderising.array; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; + +/** + * Created by songbao.yang on 2017/3/2. + * + */ +public class ArrayUtilTest { + + private ArrayUtil arrayUtil; + + @Before + public void setUp() throws Exception { + arrayUtil = new ArrayUtil(); + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void reverseArray() throws Exception { + + int[][] actualAndExpected = { + {}, {}, {0}, {0}, + {1,2,3,4,5,6}, {6,5,4,3,2,1}, + {7,9,30,3,4}, {4,3,30,9,7} + }; + + for (int i = 0; i < actualAndExpected.length; i += 2) { + int[] acutal = actualAndExpected[i]; + int[] expected = actualAndExpected[i+1]; + arrayUtil.reverseArray(acutal); + Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, acutal)); + } + } + + @Test + public void removeZero() throws Exception { + int[][] actualAndExpected = { + {}, {}, {0}, {}, + {1,0,3,0,5,0}, {1,3,5}, + {1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}, {1,3,4,5,6,6,5,4,7,6,7,5} + }; + + for (int i = 0; i < actualAndExpected.length; i += 2) { + int[] acutal = actualAndExpected[i]; + int[] expected = actualAndExpected[i+1]; + int[] ints = arrayUtil.removeZero(acutal); + Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, ints)); + } + } + + @Test + public void merge() throws Exception { + int[][] actualAndExpected = { + {}, {}, {}, + {}, {0}, {0}, + {3,5,7,8}, {4,5,6,7},{3,4,5,6,7,8}, + {1,2,3,4,5,}, {6,7,8,9,10}, {1,2,3,4,5,6,7,8,9,10} + }; + + for (int i = 0; i < actualAndExpected.length; i += 3) { + int[] array1 = actualAndExpected[i]; + int[] array2 = actualAndExpected[i+1]; + int[] expected = actualAndExpected[i+2]; + int[] result = arrayUtil.merge(array1, array2); + Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, result)); + } + + } + + @Test + public void grow() throws Exception { + int[][] actualAndExpected = { + {}, {}, + {1}, {}, + {5}, {0,0,0,0,0}, + {0},{2,3,6}, + {3}, {2,3,6,0,0,0} + }; + + for (int i = 0; i < actualAndExpected.length; i += 3) { + int[] oldArray = actualAndExpected[i]; + int size = actualAndExpected[i+1][0]; + int[] expected = actualAndExpected[i+2]; + int[] newArray = arrayUtil.grow(oldArray, size); + Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, newArray)); + } + } + + @Test + public void fibonacci() throws Exception { + int[][] actualAndExpected = { + {0}, {}, + {1}, {}, + {2}, {1,1}, + {3}, {1,1,2}, + {4}, {1,1,2,3}, + {15}, {1,1,2,3,5,8,13}, + }; + + for (int i = 0; i < actualAndExpected.length; i += 2) { + int max = actualAndExpected[i][0]; + int[] expected = actualAndExpected[i+1]; + int[] actual = arrayUtil.fibonacci(max); + Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, actual)); + } + } + + @Test + public void getPrimes() throws Exception { + int[][] actualAndExpected = { + {-1}, {}, + {0}, {}, + {1}, {}, + {2}, {}, + {3}, {2}, + {4}, {2,3}, + {23}, {2,3,5,7,11,13,17,19}, + }; + + for (int i = 0; i < actualAndExpected.length; i += 2) { + int max = actualAndExpected[i][0]; + int[] expected = actualAndExpected[i+1]; + int[] actual = arrayUtil.getPrimes(max); + Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, actual)); + } + } + + @Test + public void getPerfectNumbers() throws Exception { + int[][] actualAndExpected = { + {-1}, {}, + {0}, {}, + {1}, {}, + {2}, {}, + {7}, {6}, + {30}, {6,28}, + {500}, {6,28,496}, + {10000}, {6,28,496,8128} + }; + + for (int i = 0; i < actualAndExpected.length; i += 2) { + int max = actualAndExpected[i][0]; + int[] expected = actualAndExpected[i+1]; + int[] actual = arrayUtil.getPerfectNumbers(max); + Assert.assertTrue("wrong index: " + String.valueOf(i), isArrayEqual(expected, actual)); + } + } + + @Test + public void join() throws Exception { + int[][] arrays = { + {}, + {3,8,9}, + {1}, + {0,0,0,0,0}, + {1,2,3,4,5} + }; + String[] separators = {"", "-", "+", "*", "00"}; + String[] expecteds = { + "", + "3-8-9", + "1", + "0*0*0*0*0", + "1002003004005" + }; + for (int i = 0; i < arrays.length; i++) { + int[] array = arrays[i]; + String separator = separators[i]; + String expected = expecteds[i]; + String actual = arrayUtil.join(array, separator); + Assert.assertTrue("wrong index: " + String.valueOf(i), expected.equals(actual)); + } + } + + private boolean isArrayEqual(int[] expected, int[] actual){ + if (expected.length != actual.length){ + System.out.println("expected.length != actual.length"); + System.out.println("expected: " + Arrays.toString(expected)); + System.out.println("actual: " + Arrays.toString(actual)); + return false; + } + + for (int i = 0; i < expected.length; i++) { + if (expected[i] != actual[i]){ + System.out.println("expected[i] != actual[i]"); + System.out.println("expected: " + Arrays.toString(expected)); + System.out.println("actual: " + Arrays.toString(actual)); + return false; + } + } + + return true; + } + +} \ No newline at end of file diff --git a/group05/578505552/src/test/java/com/coderising/download/DownloadThreadTest.java b/group05/578505552/src/test/java/dataStruct/com/coderising/download/DownloadThreadTest.java similarity index 80% rename from group05/578505552/src/test/java/com/coderising/download/DownloadThreadTest.java rename to group05/578505552/src/test/java/dataStruct/com/coderising/download/DownloadThreadTest.java index eaa651776c..dbbb80a91a 100644 --- a/group05/578505552/src/test/java/com/coderising/download/DownloadThreadTest.java +++ b/group05/578505552/src/test/java/dataStruct/com/coderising/download/DownloadThreadTest.java @@ -1,16 +1,15 @@ -package com.coderising.download; +package dataStruct.com.coderising.download; -import com.coderising.download.api.Connection; -import com.coderising.download.api.DownloadListener; -import com.coderising.download.impl.ConnectionManagerImpl; +import dataStruct.com.coderising.download.DownloadThread; +import dataStruct.com.coderising.download.api.Connection; +import dataStruct.com.coderising.download.api.DownloadListener; +import dataStruct.com.coderising.download.impl.ConnectionManagerImpl; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.File; -import static org.junit.Assert.*; - /** * Created by songbao.yang on 2017/3/11. */ diff --git a/group05/578505552/src/test/java/dataStruct/com/coderising/download/FileDownloaderTest.java b/group05/578505552/src/test/java/dataStruct/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..cb5748f4e6 --- /dev/null +++ b/group05/578505552/src/test/java/dataStruct/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,49 @@ +package dataStruct.com.coderising.download; + +import dataStruct.com.coderising.download.api.ConnectionManager; +import dataStruct.com.coderising.download.api.DownloadListener; +import dataStruct.com.coderising.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class FileDownloaderTest { + boolean downloadFinished = false; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/image/h%3D360/sign=9bb90992550fd9f9bf17536f152cd42b/9a504fc2d5628535959cf4cf94ef76c6a6ef63db.jpg"; + + FileDownloader downloader = new FileDownloader(url); + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + downloader.setListener(new DownloadListener() { + public void notifyFinished() { + downloadFinished = true; + } + }); + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + } + +} diff --git a/group05/578505552/src/test/java/com/coderising/download/impl/ConnectionImplTest.java b/group05/578505552/src/test/java/dataStruct/com/coderising/download/impl/ConnectionImplTest.java similarity index 85% rename from group05/578505552/src/test/java/com/coderising/download/impl/ConnectionImplTest.java rename to group05/578505552/src/test/java/dataStruct/com/coderising/download/impl/ConnectionImplTest.java index 142540943e..967b4520a2 100644 --- a/group05/578505552/src/test/java/com/coderising/download/impl/ConnectionImplTest.java +++ b/group05/578505552/src/test/java/dataStruct/com/coderising/download/impl/ConnectionImplTest.java @@ -1,13 +1,11 @@ -package com.coderising.download.impl; +package dataStruct.com.coderising.download.impl; -import com.coderising.download.api.Connection; -import com.coderising.download.api.ConnectionManager; +import dataStruct.com.coderising.download.api.Connection; +import dataStruct.com.coderising.download.impl.ConnectionManagerImpl; import org.junit.After; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.*; - /** * Created by songbao.yang on 2017/3/11. */ diff --git a/group05/578505552/src/test/java/dataStruct/com/coderising/litestruts/StrutsTest.java b/group05/578505552/src/test/java/dataStruct/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..bdb0334ae5 --- /dev/null +++ b/group05/578505552/src/test/java/dataStruct/com/coderising/litestruts/StrutsTest.java @@ -0,0 +1,40 @@ +package dataStruct.com.coderising.litestruts; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() { + + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } +} diff --git a/group05/578505552/src/test/java/dataStruct/com/coding/basic/BinaryTreeNodeTest.java b/group05/578505552/src/test/java/dataStruct/com/coding/basic/BinaryTreeNodeTest.java new file mode 100644 index 0000000000..ee7ecd6e36 --- /dev/null +++ b/group05/578505552/src/test/java/dataStruct/com/coding/basic/BinaryTreeNodeTest.java @@ -0,0 +1,36 @@ +package dataStruct.com.coding.basic; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by songbao.yang on 2017/2/28. + * + */ +public class BinaryTreeNodeTest { + + private BinaryTreeNode node; + + @Before + public void setUp() throws Exception { + node = new BinaryTreeNode(); + node.setData(100); + node.setLeft(null); + node.setRight(null); + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void insert() throws Exception { + + for (int i = 0; i < 100; i++) { + int ele = (int)Math.floor(Math.random() * 200); + node.insert(ele); + } + } +} \ No newline at end of file diff --git a/group05/578505552/src/test/java/com/coding/basic/ListTest.java b/group05/578505552/src/test/java/dataStruct/com/coding/basic/ListTest.java similarity index 94% rename from group05/578505552/src/test/java/com/coding/basic/ListTest.java rename to group05/578505552/src/test/java/dataStruct/com/coding/basic/ListTest.java index 0c786de96c..9196c37f4c 100644 --- a/group05/578505552/src/test/java/com/coding/basic/ListTest.java +++ b/group05/578505552/src/test/java/dataStruct/com/coding/basic/ListTest.java @@ -1,100 +1,100 @@ -package com.coding.basic; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -/** - * Created by songbao.yang on 2017/2/21. - * - */ -public class ListTest { - - private List list; - - public static final int SIZE = 10000; - - @Before - public void setUp() throws Exception { - -// list = new ArrayList(); - list = new LinkedList(); - } - - @After - public void tearDown() throws Exception { - - } - - @Test - public void add() throws Exception { - - for (int i = 0; i < SIZE; i++) { - list.add(i); - Assert.assertEquals(i+1, list.size()); - } - } - - @Test - public void add1() throws Exception { - - add(); - for (int i = 0; i < 1000; i++) { - int oldSize = list.size(); - int randomIndex = (int)Math.floor(Math.random() * oldSize); - - list.add(randomIndex, randomIndex); - int newSize = list.size(); - - Assert.assertEquals(newSize, oldSize+1); - Assert.assertEquals(list.get(randomIndex), randomIndex); - } - } - - @Test - public void get() throws Exception { - - add(); - for (int i = 0; i < SIZE * 100; i++) { - int randomIndex = (int)Math.floor(Math.random() * list.size()); - if(randomIndex < 0 || randomIndex >= SIZE){ - System.out.println("illegal index: " + randomIndex); - throw new RuntimeException(); - } - int o = (Integer) list.get(randomIndex); - Assert.assertEquals(randomIndex, o); - } - } - - @Test - public void remove() throws Exception { - - add(); - for (int i = 0; i < SIZE; i++) { - int oldSize = list.size(); - int randomIndex = (int)Math.floor(Math.random() * oldSize); - list.remove(randomIndex); - int newSize = list.size(); - Assert.assertEquals(newSize, oldSize-1); - } - } - - @Test - public void size() throws Exception { - - } - - @Test - public void iterator() throws Exception { - add(); - Iterator iterator1 = list.iterator(); - int i = 0; - while (iterator1.hasNext()){ - Object next = iterator1.next(); - Assert.assertEquals(i, next); - i++; - } - } - +package dataStruct.com.coding.basic; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by songbao.yang on 2017/2/21. + * + */ +public class ListTest { + + private List list; + + public static final int SIZE = 10000; + + @Before + public void setUp() throws Exception { + +// list = new ArrayList(); + list = new LinkedList(); + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void add() throws Exception { + + for (int i = 0; i < SIZE; i++) { + list.add(i); + Assert.assertEquals(i+1, list.size()); + } + } + + @Test + public void add1() throws Exception { + + add(); + for (int i = 0; i < 1000; i++) { + int oldSize = list.size(); + int randomIndex = (int)Math.floor(Math.random() * oldSize); + + list.add(randomIndex, randomIndex); + int newSize = list.size(); + + Assert.assertEquals(newSize, oldSize+1); + Assert.assertEquals(list.get(randomIndex), randomIndex); + } + } + + @Test + public void get() throws Exception { + + add(); + for (int i = 0; i < SIZE * 100; i++) { + int randomIndex = (int)Math.floor(Math.random() * list.size()); + if(randomIndex < 0 || randomIndex >= SIZE){ + System.out.println("illegal index: " + randomIndex); + throw new RuntimeException(); + } + int o = (Integer) list.get(randomIndex); + Assert.assertEquals(randomIndex, o); + } + } + + @Test + public void remove() throws Exception { + + add(); + for (int i = 0; i < SIZE; i++) { + int oldSize = list.size(); + int randomIndex = (int)Math.floor(Math.random() * oldSize); + list.remove(randomIndex); + int newSize = list.size(); + Assert.assertEquals(newSize, oldSize-1); + } + } + + @Test + public void size() throws Exception { + + } + + @Test + public void iterator() throws Exception { + add(); + Iterator iterator1 = list.iterator(); + int i = 0; + while (iterator1.hasNext()){ + Object next = iterator1.next(); + Assert.assertEquals(i, next); + i++; + } + } + } \ No newline at end of file diff --git a/group05/578505552/src/test/java/dataStruct/com/coding/basic/QueueTest.java b/group05/578505552/src/test/java/dataStruct/com/coding/basic/QueueTest.java new file mode 100644 index 0000000000..856258a713 --- /dev/null +++ b/group05/578505552/src/test/java/dataStruct/com/coding/basic/QueueTest.java @@ -0,0 +1,75 @@ +package dataStruct.com.coding.basic; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by songbao.yang on 2017/2/24. + */ +public class QueueTest { + + private static final int SIZE = 2000; + private Queue queue; + + @Before + public void setUp() throws Exception { + queue = new Queue(); + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void enQueue() throws Exception { + for (int i = 0; i < SIZE; i++) { + queue.enQueue(i); + assertEquals(i+1, queue.size()); + } + } + + @Test + public void deQueue1() throws Exception { + enQueue(); + + int i = 0; + int startSize = queue.size(); + while (!queue.isEmpty()) { + assertEquals(startSize - i, queue.size()); + Object o = queue.deQueue(); + assertEquals(SIZE - i - 1, queue.size()); + Assert.assertEquals(i, o); + i++; + } + } + + @Test + public void deQueue2() throws Exception { + enQueue(); + int startSize = queue.size(); + + for (int i = 0; i < startSize; i++) { + queue.deQueue(); + assertEquals(startSize - 1, queue.size()); + queue.enQueue(i+1000); + assertEquals(startSize, queue.size()); + } + + } + + @Test + public void isEmpty() throws Exception { + + } + + @Test + public void size() throws Exception { + + } + +} \ No newline at end of file diff --git a/group05/578505552/src/test/java/dataStruct/com/coding/basic/StackTest.java b/group05/578505552/src/test/java/dataStruct/com/coding/basic/StackTest.java new file mode 100644 index 0000000000..c58643c31a --- /dev/null +++ b/group05/578505552/src/test/java/dataStruct/com/coding/basic/StackTest.java @@ -0,0 +1,65 @@ +package dataStruct.com.coding.basic; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by songbao.yang on 2017/2/24. + * + */ +public class StackTest { + + private Stack stack; + + public static final int SIZE = 100; + + @Before + public void setUp() throws Exception { + stack = new Stack(); + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void push() throws Exception { + for (int i = 0; i < SIZE; i++) { + stack.push(i); + assertEquals(i+1, stack.size()); + } + System.out.println(); + } + + @Test + public void pop() throws Exception { + push(); + int beginSize = stack.size(); + for (int i = 0; i < beginSize; i++) { + Object ele = stack.pop(); + assertEquals(beginSize-i-1, stack.size()); + Assert.assertEquals(beginSize-i-1, ele); + } + } + + @Test + public void peek() throws Exception { + + } + + @Test + public void isEmpty() throws Exception { + + } + + @Test + public void size() throws Exception { + + } + +} \ No newline at end of file diff --git a/group05/578505552/src/test/java/dataStruct/com/coding/basic/linklist/LRUPageFrameTest.java b/group05/578505552/src/test/java/dataStruct/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..ffeaa4a747 --- /dev/null +++ b/group05/578505552/src/test/java/dataStruct/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package dataStruct.com.coding.basic.linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} diff --git a/group05/578505552/src/test/java/miniJvm/com/coderising/jvm/loader/ClassFileloaderTest.java b/group05/578505552/src/test/java/miniJvm/com/coderising/jvm/loader/ClassFileloaderTest.java new file mode 100644 index 0000000000..97410772aa --- /dev/null +++ b/group05/578505552/src/test/java/miniJvm/com/coderising/jvm/loader/ClassFileloaderTest.java @@ -0,0 +1,70 @@ +package miniJvm.com.coderising.jvm.loader; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ClassFileloaderTest { + + static String path1 = "D:\\project\\Learn\\coding2017\\group05\\578505552\\target\\classes"; + static String path2 = "C:\\temp"; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + String clzPath = loader.getClassPath(); + Assert.assertEquals(path1+";"+path2,clzPath); + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "miniJvm.com.coderising.jvm.loader.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1141, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "miniJvm.com.coderising.jvm.loader.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + String acctualValue = this.byteToHexString(codes); + Assert.assertEquals("cafebabe", acctualValue); + } + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i map = new HashMap<>(); - Struts.runAction("login", map); - - } -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/array/ArrayUtil.java b/group11/1178243325/DataStructure/src/main/java/com/coderising/array/ArrayUtil.java deleted file mode 100644 index f94d5d01c4..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/array/ArrayUtil.java +++ /dev/null @@ -1,229 +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 static void reverseArray(int[] origin){ - if (origin == null) { - return; - } - - int length = origin.length; - int[] temp = new int[length]; - for (int i = 0; i < length; i++) - temp[i] = origin[i]; - for (int i = length - 1, j = 0; i >= 0 && j < length; i--, j++) - origin[j] = temp[i]; - } - - /** - * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} - * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: - * {1,3,4,5,6,6,5,4,7,6,7,5} - * @param oldArray - * @return - */ - - public static int[] removeZero(int[] oldArray){ - if (oldArray == null) { - return null; - } - - int zeroCount = 0; - for (int i = 0; i < oldArray.length; i++) { - if (oldArray[i] == 0) - zeroCount++; - } - int[] newArray = new int[oldArray.length-zeroCount]; - for (int i = 0, j = 0; i < oldArray.length && j < newArray.length; i++) { - if (oldArray[i] != 0) { - newArray[j] = oldArray[i]; - j++; - } - } - return newArray; - } - - /** - * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 - * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 - * @param array1 - * @param array2 - * @return - */ - - public static int[] merge(int[] array1, int[] array2){ - if (array1 == null && array2 == null) - return null; - int index1 = 0, index2 = 0; - int[] array3 = new int[array1.length + array2.length]; - int index = 0; - while (index1 != array1.length && index2 != array2.length) { - if (array1[index1] < array2[index2]) { - array3[index++] = array1[index1++]; - } else if (array1[index1] > array2[index2]) { - array3[index++] = array2[index2++]; - } else if (array1[index1] == array2[index2]){ - array3[index++] = array1[index1++]; - index2++; - } - } - - if (index1 == array1.length && index2 != array2.length) { - for (int i = index2; i < array2.length; i++) - array3[index++] = array2[i]; - } else if (index2 == array2.length && index1 != array1.length) { - for (int i = index1; i < array1.length; i++) { - array3[index++] = array1[i]; - } - } - - int[] newArray = new int[index]; - for (int i = 0; i < newArray.length; i++) - newArray[i] = array3[i]; - 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){ - if (size <= 0) - return null; - int[] newArray = new int[oldArray.length + size]; - for (int i = 0; i < oldArray.length; i++) { - newArray[i] = oldArray[i]; - } - return newArray; - } - - /** - * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 - * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] - * max = 1, 则返回空数组 [] - * @param max - * @return - */ - public static int[] fibonacci(int max){ - if (max < 1) - return null; - if (max == 1) - return null; - int[] array = new int[max]; - int i = 0; - int value = fibonaccis(i+1); - while ( value < max) { - array[i++] = value; - value = fibonaccis(i+1); - } - int[] newArray = new int[i]; - for (int j = 0; j < newArray.length; j++) { - newArray[j] = array[j]; - } - return newArray; - } - - private static int fibonaccis(int n) { - if (n <=0) - return 0; - if (n == 1 || n ==2 ) - return 1; - return fibonaccis(n-1)+fibonaccis(n-2); - } - - /** - * 返回小于给定最大值max的所有素数数组 - * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] - * @param max - * @return - */ - public static int[] getPrimes(int max){ - if (max <= 1) { - return null; - } - int[] array = new int[max]; - int index = 0; - for (int i = 2; i < max; i++) { - if (i == 2 || i == 3 || i == 5 || i == 7) - array[index++] = i; - if (i%2 !=0 && i%3 != 0 && i%5 != 0 && i%7 != 0) - array[index++] = i; - } - int[] newArray = new int[index]; - for (int i = 0; i < newArray.length; i++) { - newArray[i] = array[i]; - } - - return newArray; - } - - /** - * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 - * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 - * @param max - * @return - */ - public static int[] getPerfectNumbers(int max){ - if (max <= 0) - return null; - int[] array = new int[max]; - int index = 0; - for (int i = 1; i < max; i++) { - if (isPerfectNumber(i)) - array[index++] = i; - } - - int[] newArray = new int[index]; - for (int i = 0; i < newArray.length; i++) - newArray[i] = array[i]; - - return newArray; - } - - private static boolean isPerfectNumber(int n) { - int sum = 0; - int i = 1; - while (i < n) { - if (n%i == 0) - sum += i; - i++; - } - if (sum == n) - return true; - return false; - } - /** - * 用seperator 把数组 array给连接起来 - * 例如array= [3,8,9], seperator = "-" - * 则返回值为"3-8-9" - * @param array - * @param s - * @return - */ - public static String join(int[] array, String seperator){ - if (array == null) - return null; - StringBuilder str = new StringBuilder(); - for (int i = 0; i < array.length; i++) { - if (i == array.length-1) - str.append(array[i]); - else - str.append(array[i] + seperator); - } - return str.toString(); - } - - -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/.Struts.java.swp b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/.Struts.java.swp deleted file mode 100644 index 1f45a5f25e..0000000000 Binary files a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/.Struts.java.swp and /dev/null differ diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/LoginAction.java b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/LoginAction.java deleted file mode 100644 index 1005f35a29..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/LoginAction.java +++ /dev/null @@ -1,39 +0,0 @@ -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/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/Struts.java b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/Struts.java deleted file mode 100644 index b3bd421435..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/Struts.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.coderising.litestruts; - -import java.util.Map; -import java.util.HashMap; -import java.lang.reflect.Method; -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 { - String targetClassName = XmlUtil.parseXML("struts.xml", actionName); - Class targetClass = Class.forName(targetClassName); - - Method setName = targetClass.getMethod("setName", String.class); - Method setPassword = targetClass.getMethod("setPassword", String.class); - Object object = targetClass.newInstance(); - - setName.invoke(object, parameters.get("name")); - setPassword.invoke(object, parameters.get("password")); - - Method execute = targetClass.getMethod("execute"); - String result = (String)execute.invoke(object); - - Method getMessage = targetClass.getMethod("getMessage"); - String message = (String)getMessage.invoke(object); - - Map params = new HashMap(); - params.put("message", message); - String jspUrl = XmlUtil.getJspUrl("struts.xml", actionName, result); - View view = new View(); - view.setJsp(jspUrl); - view.setParameters(params); - return view; - - } catch (Exception e) { - e.printStackTrace(); - } - - - return null; - } - -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/StrutsTest.java b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/StrutsTest.java deleted file mode 100644 index a44c1878ac..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/StrutsTest.java +++ /dev/null @@ -1,43 +0,0 @@ -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/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/View.java b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/View.java deleted file mode 100644 index 0194c681f6..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/View.java +++ /dev/null @@ -1,23 +0,0 @@ -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/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/XmlUtil.java b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/XmlUtil.java deleted file mode 100644 index d200452cc8..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/XmlUtil.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.coderising.litestruts; - -import java.io.*; -import java.util.*; -import org.dom4j.Attribute; -import org.dom4j.Document; -import org.dom4j.Element; -import org.dom4j.io.SAXReader; -import org.dom4j.io.XMLWriter; -public class XmlUtil { - - public static String parseXML(String filePath, String actionName) { - try { - File file = new File(filePath); - SAXReader reader = new SAXReader(); - Document doc = reader.read(file); - Element root = doc.getRootElement(); - for (Iterator iter = root.elementIterator("action"); iter.hasNext();) { - Element element = (Element)iter.next(); - Attribute nameAttr = element.attribute("name"); - if (nameAttr.getValue().equals(actionName)) { - Attribute classAttr = element.attribute("class"); - return classAttr.getValue(); - } - } - } catch (Exception e) { - e.printStackTrace(); - System.out.println("parse error"); - } - return null; - } - - public static String getJspUrl(String filePath, String actionName, String resultName) { - try { - File file = new File(filePath); - SAXReader reader = new SAXReader(); - Document doc = reader.read(file); - Element root = doc.getRootElement(); - for (Iterator iter = root.elementIterator("action"); iter.hasNext();) { - Element element = (Element)iter.next(); - Attribute nameAttr = element.attribute("name"); - if (nameAttr.getValue().equals(actionName)) { - for (Iterator ite = element.elementIterator("result"); ite.hasNext();) { - Element ele = (Element)ite.next(); - Attribute resultAttr = ele.attribute("name"); - if (resultAttr.getValue().equals(resultName)) { - return ele.getText(); - } - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/struts.xml b/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/struts.xml deleted file mode 100644 index ae0ce37fd8..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coderising/litestruts/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/ArrayList.java b/group11/1178243325/DataStructure/src/main/java/com/coding/basic/ArrayList.java deleted file mode 100644 index f6cd4c38fc..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/ArrayList.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.coding.basic; - -import com.coding.basic.exception.*; -public class ArrayList implements List { - - private int size; - private Object[] elementData; - - public ArrayList () { - size = 0; - elementData = new Object[100]; - } - - public void add(Object o){ - add(size(), o); - } - - public void add(int index, Object o){ - if (size() == elementData.length) - ensureCapacity( size() * 2 + 1); - if (index > size() || index < 0) { //index == size时相当于在尾后插入 - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - for (int i = size; i > index; i--) { - elementData[i] = elementData[i-1]; - } - elementData[index] = o; - size++; - - } - - private void ensureCapacity(int newCapacity) { - if (newCapacity < size()) - return; - Object[] old = elementData; - elementData = new Object[newCapacity]; - for (int i = 0; i < size(); i++) { - elementData[i] = old[i]; - } - } - - public Object get(int index){ - if (index >= size() || index < 0) { //获取时,index==size()越界 - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - return elementData[index]; - } - - private String outOfBoundsMsg(int index) { - return "Index:" + index + ", Size:" + size; - } - - public Object remove(int index){ - if (index >= size() || index < 0) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - Object old = elementData[index]; - for (int i = index; i < size(); i++) { - elementData[i] = elementData[i+1]; - } - size--; - return old; - } - - /*获取表内容量*/ - public int size(){ - return size; - } - - public Iterator iterator(){ - return new ArrayListIterator(); - } - - public class ArrayListIterator implements Iterator { - private final int ONLY_CAPACITY = size; - private int index; - public ArrayListIterator() { - index = 0; - } - - @Override - public boolean hasNext() { - if (ONLY_CAPACITY != size) - throw new ConcurrentModificationException("此对象没有进行修改同步"); - return index != size; - } - - @Override - public Object next() { - if (ONLY_CAPACITY != size) - throw new ConcurrentModificationException("此对象没有进行修改同步"); - if (index >= ONLY_CAPACITY) - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - return elementData[index++]; - } - } -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/BinaryTreeNode.java b/group11/1178243325/DataStructure/src/main/java/com/coding/basic/BinaryTreeNode.java deleted file mode 100644 index 1cf38aee30..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/BinaryTreeNode.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.coding.basic; - -public class BinaryTreeNode { - - private Object data; - private BinaryTreeNode left; - private BinaryTreeNode right; - - public Object getData() { - return data; - } - - public void setData(Object data) { - this.data = data; - } - - public BinaryTreeNode getLeft() { - return left; - } - - public void setLeft(BinaryTreeNode left) { - this.left = left; - } - - public BinaryTreeNode getRight() { - return right; - } - - public void setRight(BinaryTreeNode right) { - this.right = right; - } - -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/LinkedList.java b/group11/1178243325/DataStructure/src/main/java/com/coding/basic/LinkedList.java deleted file mode 100644 index d82349089b..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/LinkedList.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.coding.basic; - -import com.coding.basic.exception.*; -public class LinkedList implements List { - - private Node head; - private int size; - public LinkedList() { - head = new Node(null, null); - size = 0; - } - - public void add(Object o){ - add(size, o); - } - - public void add(int index , Object o){ - if (index > size || index < 0) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - Node frontNode = getNode(index-1); - Node newNode = new Node(o, frontNode.next); - frontNode.next = newNode; - size++; - - } - - private Node getNode(int index) { - Node node = head; - int i = 0; - while(node.next != null && i <= index) { - node = node.next; - i++; - } - return node; - } - - public Object get(int index){ - if (index >= size || index < 0) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - - Node node = getNode(index); - return node.data; - } - - public Object remove(int index){ - if (index >= size || index < 0) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - Node frontNode = getNode(index-1); - Node oldNode = getNode(index); - frontNode.next = oldNode.next; - size--; - return oldNode.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(); - } - - private class LinkedListIterator implements Iterator { - int index; - final int capacity = size; - LinkedListIterator() { - index = 0; - } - @Override - public boolean hasNext() { - if (capacity != size) - throw new ConcurrentModificationException("此对象没有修改同步"); - return index < capacity; - } - - @Override - public Object next() { - if (capacity != size) - throw new ConcurrentModificationException("此对象没有修改同步"); - if (index >= capacity) - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - return get(index++); - } - } - - private String outOfBoundsMsg(int index) { - return "index:" + index + ", size:" + size; - } - - private static class Node { - Object data; - Node next; - - Node(Object data, Node next) { - this.data = data; - this.next = next; - } - - void setData(Object data) { - this.data = data; - } - - Object getData() { - return data; - } - - void setNext(Node next) { - this.next = next; - } - - Object getNext() { - return next; - } - } -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Queue.java b/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Queue.java deleted file mode 100644 index a5c31f5a09..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Queue.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.coding.basic; -import com.coding.basic.exception.*; -public class Queue { - - private LinkedList elementData; - - public Queue() { - elementData = new LinkedList(); - } - - public void enQueue(Object o){ - elementData.addLast(o); - } - - public Object deQueue(){ - if (isEmpty()) { - throw new EmptyQueueException("队空"); - } - Object result = elementData.removeFirst(); - return result; - } - - public boolean isEmpty(){ - return elementData.size() == 0; - } - - public int size(){ - return elementData.size(); - } -} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Stack.java b/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Stack.java deleted file mode 100644 index e41c662792..0000000000 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Stack.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.coding.basic; - -import com.coding.basic.exception.*; -public class Stack { - - private ArrayList elementData; - public Stack() { - elementData = new ArrayList(); - } - - public void push(Object o){ - elementData.add(o); - } - - public Object pop(){ - if (isEmpty()) { - throw new EmptyStackException("栈空"); - } - Object result = elementData.get(size()-1); - elementData.remove(size()-1); - return result; - } - - public Object peek(){ - if (isEmpty()) { - throw new EmptyStackException("栈空"); - } - return elementData.get(0); - } - - public boolean isEmpty(){ - return elementData.size() == 0; - } - - public int size(){ - return elementData.size(); - } -} diff --git a/group11/1178243325/DataStructure/src/main/resources/struts.xml b/group11/1178243325/DataStructure/src/main/resources/struts.xml deleted file mode 100644 index ae0ce37fd8..0000000000 --- a/group11/1178243325/DataStructure/src/main/resources/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - diff --git a/group11/1178243325/DataStructure/struts.xml b/group11/1178243325/DataStructure/struts.xml deleted file mode 100644 index 0582b7d4ea..0000000000 --- a/group11/1178243325/DataStructure/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - diff --git a/group11/1178243325/week01/build.gradle b/group11/1178243325/week01/build.gradle new file mode 100644 index 0000000000..50d1380b3f --- /dev/null +++ b/group11/1178243325/week01/build.gradle @@ -0,0 +1,9 @@ +apply plugin: 'java' + +repositories { + mavenCentral(); +} + +dependencies { + testCompile("junit:junit:4.12") +} diff --git a/group11/1178243325/week01/readme.md b/group11/1178243325/week01/readme.md new file mode 100644 index 0000000000..314098dd59 --- /dev/null +++ b/group11/1178243325/week01/readme.md @@ -0,0 +1,16 @@ +## 讲课内容: +- 17-2-15: 社群kickoff +- 17-2-19:讲解Java自测题和基本数据结构 +- 17-2-22:计算机组成原理和计算机编程语言 +- 17-2-26:程序的机器级表示 + +## 第一周作业(2-15 至 2-26) +- 实现各种基本数据结构(ArrayList, Stack, LinkedList, Queue, Tree, Iterator) +- 写一篇介绍CPU,内存,硬盘,指令以及他们之间的关系 + +## 完成情况: +- 基本数据结构已完成 +- [文章地址](http://www.jianshu.com/p/8d8379aa1281) + +## 我的收获: +- [漫谈计算机组成原理和编程语言](http://www.jianshu.com/p/07df48adf338) diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/Iterator.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/Iterator.java new file mode 100644 index 0000000000..1e73a2a4b9 --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/Iterator.java @@ -0,0 +1,6 @@ +package com.sprint.basic; + +public interface Iterator { + public boolean hasNext(); + public Object next(); +} diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/ConcurrentModificationException.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/ConcurrentModificationException.java new file mode 100644 index 0000000000..c91c388bbd --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/ConcurrentModificationException.java @@ -0,0 +1,9 @@ +package com.sprint.basic.exception; + +public class ConcurrentModificationException extends RuntimeException { + public ConcurrentModificationException() {} + public ConcurrentModificationException(String msg) { + super(msg); + } +} + diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyQueueException.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyQueueException.java similarity index 81% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyQueueException.java rename to group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyQueueException.java index 2ee7aa4ee7..ddf89ac120 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyQueueException.java +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyQueueException.java @@ -1,4 +1,4 @@ -package com.coding.basic.exception; +package com.sprint.basic.exception; public class EmptyQueueException extends RuntimeException { public EmptyQueueException() {} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyStackException.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyStackException.java similarity index 81% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyStackException.java rename to group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyStackException.java index 2a5ae4055d..d654c7cd16 100644 --- a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/EmptyStackException.java +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/exception/EmptyStackException.java @@ -1,4 +1,4 @@ -package com.coding.basic.exception; +package com.sprint.basic.exception; public class EmptyStackException extends RuntimeException { public EmptyStackException() {} diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/list/ArrayList.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/ArrayList.java new file mode 100644 index 0000000000..fb64e93f36 --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/ArrayList.java @@ -0,0 +1,99 @@ +package com.sprint.basic.list; + +import com.sprint.basic.exception.ConcurrentModificationException; +import com.sprint.basic.Iterator; +public class ArrayList implements List { + + private int size; + private Object[] elementData; + + public ArrayList () { + size = 0; + elementData = new Object[100]; + } + + public boolean add(Object o) { + add(size(), o); + return true; + } + + public boolean add(int index, Object o){ + if (size() == elementData.length) + ensureCapacity( size() * 2 + 1); + if (index > size() || index < 0) { //index == size时相当于在尾后插入 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + for (int i = size; i > index; i--) { + elementData[i] = elementData[i-1]; + } + elementData[index] = o; + size++; + return true; + } + + private void ensureCapacity(int newCapacity) { + if (newCapacity < size()) + return; + Object[] old = elementData; + elementData = new Object[newCapacity]; + for (int i = 0; i < size(); i++) { + elementData[i] = old[i]; + } + } + + public Object get(int index){ + if (index >= size() || index < 0) { //获取时,index==size()越界 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + return elementData[index]; + } + + private String outOfBoundsMsg(int index) { + return "Index:" + index + ", Size:" + size; + } + + public Object remove(int index){ + if (index >= size() || index < 0) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + Object old = elementData[index]; + for (int i = index; i < size(); i++) { + elementData[i] = elementData[i+1]; + } + size--; + return old; + } + + /*获取表内容量*/ + public int size(){ + return size; + } + + public Iterator iterator(){ + return new ArrayListIterator(); + } + + public class ArrayListIterator implements Iterator { + private final int ONLY_CAPACITY = size; + private int index; + public ArrayListIterator() { + index = 0; + } + + @Override + public boolean hasNext() { + if (ONLY_CAPACITY != size) + throw new ConcurrentModificationException("此对象没有进行修改同步"); + return index != size; + } + + @Override + public Object next() { + if (ONLY_CAPACITY != size) + throw new ConcurrentModificationException("此对象没有进行修改同步"); + if (index >= ONLY_CAPACITY) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + return elementData[index++]; + } + } +} diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/list/LinkedList.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/LinkedList.java new file mode 100644 index 0000000000..503f41f65b --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/LinkedList.java @@ -0,0 +1,160 @@ +package com.sprint.basic.list; + +import com.sprint.basic.exception.ConcurrentModificationException; +import com.sprint.basic.Iterator; +import java.util.Objects; +public class LinkedList implements List { + + private Node head; + private int size; + public LinkedList() { + head = new Node(null, null); + size = 0; + } + + public boolean add(Object o) { + add(size, o); + return true; + } + + public boolean add(int index , Object o) { + if (index > size || index < 0) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + Node frontNode = getNode(index-1); + Node newNode = new Node(o, frontNode.next); + frontNode.next = newNode; + size++; + return true; + } + + /*getNode getPreNodeByElement getNextNodeByElement的效率低些*/ + private Node getNode(int index) { + Node node = head; + int i = 0; + while(node.next != null && i <= index) { + node = node.next; + i++; + } + return node; + } + + private Node getPreNodeByElement(Object obj) { + if (obj != null) { + for (int i = 0; i < size(); i++) { + if (getNode(i).data == obj) { + return getNode(i-1); + } + } + } + return null; + } + + private Node getNextNodeByElement(Object obj) { + if (obj != null) { + for (int i = 0; i < size(); i++) { + if (getNode(i).data == obj) { + return getNode(i+1); + } + } + } + return null; + } + + public Object get(int index){ + if (index >= size || index < 0) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + + Node node = getNode(index); + return node.data; + } + + public Object remove(int index){ + if (index >= size || index < 0) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + Node frontNode = getNode(index-1); + Node oldNode = getNode(index); + frontNode.next = oldNode.next; + size--; + return oldNode.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(); + } + + private class LinkedListIterator implements Iterator { + int index; + final int capacity = size; + LinkedListIterator() { + index = 0; + } + @Override + public boolean hasNext() { + if (capacity != size) + throw new ConcurrentModificationException("此对象没有修改同步"); + return index < capacity; + } + + @Override + public Object next() { + if (capacity != size) + throw new ConcurrentModificationException("此对象没有修改同步"); + if (index >= capacity) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + return get(index++); + } + } + + private String outOfBoundsMsg(int index) { + return "index:" + index + ", size:" + size; + } + + private static class Node { + Object data; + Node next; + + Node(Object data, Node next) { + this.data = data; + this.next = next; + } + + void setData(Object data) { + this.data = data; + } + + Object getData() { + return data; + } + + void setNext(Node next) { + this.next = next; + } + + Object getNext() { + return next; + } + } +} diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/list/List.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/List.java new file mode 100644 index 0000000000..0e90471a48 --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/list/List.java @@ -0,0 +1,10 @@ +package com.sprint.basic.list; +import com.sprint.basic.Iterator; +public interface List { + public boolean add(Object o); + public boolean add(int index, Object o); + public Object get(int index); + public Object remove(int index); + public int size(); + public Iterator iterator(); +} diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/queue/Queue.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/queue/Queue.java new file mode 100644 index 0000000000..47f7b98d96 --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/queue/Queue.java @@ -0,0 +1,32 @@ +package com.sprint.basic.queue; +import com.sprint.basic.exception.EmptyQueueException; +import com.sprint.basic.list.LinkedList; +public class Queue { + + private LinkedList elementData; + + public Queue() { + elementData = new LinkedList(); + } + + public boolean enQueue(Object o){ + elementData.addLast(o); + return true; + } + + public Object deQueue(){ + if (isEmpty()) { + throw new EmptyQueueException("队空"); + } + Object result = elementData.removeFirst(); + return result; + } + + public boolean isEmpty(){ + return elementData.size() == 0; + } + + public int size(){ + return elementData.size(); + } +} diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/stack/Stack.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/stack/Stack.java new file mode 100644 index 0000000000..e399dcb850 --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/stack/Stack.java @@ -0,0 +1,40 @@ +package com.sprint.basic.stack; + +import com.sprint.basic.exception.EmptyStackException; +import com.sprint.basic.list.ArrayList; +public class Stack { + + private ArrayList elementData; + public Stack() { + elementData = new ArrayList(); + } + + public boolean push(Object o){ + elementData.add(o); + return true; + } + + public Object pop(){ + if (isEmpty()) { + throw new EmptyStackException("栈空"); + } + Object result = elementData.get(size()-1); + elementData.remove(size()-1); + return result; + } + + public Object peek(){ + if (isEmpty()) { + throw new EmptyStackException("栈空"); + } + return elementData.get(0); + } + + public boolean isEmpty(){ + return elementData.size() == 0; + } + + public int size(){ + return elementData.size(); + } +} diff --git a/group11/1178243325/week01/src/main/java/com/sprint/basic/tree/BinaryTreeNode.java b/group11/1178243325/week01/src/main/java/com/sprint/basic/tree/BinaryTreeNode.java new file mode 100644 index 0000000000..efaf261521 --- /dev/null +++ b/group11/1178243325/week01/src/main/java/com/sprint/basic/tree/BinaryTreeNode.java @@ -0,0 +1,122 @@ +package com.sprint.basic.tree; + +public class BinaryTreeNode { + + private T data; + private BinaryTreeNode left; + private BinaryTreeNode right; + private int size; + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public BinaryTreeNode getLeft() { + return left; + } + + public void setLeft(BinaryTreeNode left) { + this.left = left; + } + + public BinaryTreeNode getRight() { + return right; + } + + public void setRight(BinaryTreeNode right) { + this.right = right; + } + + public BinaryTreeNode insert(T data) { + if (this.data == null) { + this.data = data; + return this; + } + int compareResult = this.data.compareTo(data); + if (compareResult > 0) { + if (this.left == null) { + this.left = new BinaryTreeNode(); + this.left.data = data; + return this.left; + } else { + return this.left.insert(data); + } + } else if (compareResult < 0) { + if (this.right == null) { + this.right = new BinaryTreeNode(); + this.right.data = data; + return this.right; + } else { + return this.right.insert(data); + } + } else { + return this; + } + } + + /*没看懂*/ + public BinaryTreeNode delete(T data) { + BinaryTreeNode treeNode = search(data); + if (treeNode == null) { + return null; + } + int compareResult = this.data.compareTo(data); + if (compareResult > 0) { + return this.left.delete(data); + } else if (compareResult < 0) { + return this.right.delete(data); + } else { + if (treeNode.right == null) { + if (this.left == null) { + this.data = null; + } else { + this.left = this; + } + } else { + this.data = (T) this.right.findMin().data; + + this.right.delete(this.data); + } + } + + return this; + } + + private BinaryTreeNode findMin() { + if (this.data == null) { + return null; + } + if (this.left == null) { + return this; + } + return this.left.findMin(); + } + + public BinaryTreeNode search(T data) { + if (this.data == null) { + return null; + } + int compareResult = this.data.compareTo(data); + if (compareResult > 0) { + if (this.left == null) { + return null; + } else { + return this.left.search(data); + } + } else if (compareResult < 0) { + if (this.right == null) { + return null; + } else { + return this.right.search(data); + } + } else { + return this; + } + } + + +} diff --git a/group11/1178243325/week01/src/test/java/com/sprint/basic/list/ArrayListTest.java b/group11/1178243325/week01/src/test/java/com/sprint/basic/list/ArrayListTest.java new file mode 100644 index 0000000000..63936c288c --- /dev/null +++ b/group11/1178243325/week01/src/test/java/com/sprint/basic/list/ArrayListTest.java @@ -0,0 +1,56 @@ +package com.sprint.basic.list; + +import com.sprint.basic.Iterator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ArrayListTest { + private List list; + + @Before + public void init() { + list = new ArrayList(); + } + + @Test + public void add() { + for (int i = 0; i < 5; i++) { + list.add(i); + } + /*Assert.assertTrue(args): if (args != true) to failed*/ + System.out.println(list); + Assert.assertTrue(list.add(5)); + Assert.assertEquals(6, list.size()); + Assert.assertTrue(list.add(3, 10)); + Assert.assertEquals(7, list.size()); + + } + + @Test + public void remove() { + add(); + Assert.assertEquals(5, list.remove(6)); + Assert.assertEquals(6, list.size()); + } + + @Test + public void get() { + add(); + Assert.assertEquals(5, list.get(6)); + } + + @Test + public void testIterator() { + for (int i = 0; i < 10; i++) { + Assert.assertTrue(list.add(i)); + } + Iterator iter = list.iterator(); + int count = 0; + while(iter.hasNext()) { + Assert.assertEquals(count, iter.next()); + count++; + } + } + +} diff --git a/group11/1178243325/week01/src/test/java/com/sprint/basic/list/LinkedListTest.java b/group11/1178243325/week01/src/test/java/com/sprint/basic/list/LinkedListTest.java new file mode 100644 index 0000000000..c5ab12aa4e --- /dev/null +++ b/group11/1178243325/week01/src/test/java/com/sprint/basic/list/LinkedListTest.java @@ -0,0 +1,56 @@ +package com.sprint.basic.list; + +import com.sprint.basic.Iterator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class LinkedListTest { + private List list; + + @Before + public void init() { + list = new LinkedList(); + } + + @Test + public void add() { + for (int i = 0; i < 5; i++) { + list.add(i); + } + /*Assert.assertTrue(args): if (args != true) to failed*/ + System.out.println(list); + Assert.assertTrue(list.add(5)); + Assert.assertEquals(6, list.size()); + Assert.assertTrue(list.add(3, 10)); + Assert.assertEquals(7, list.size()); + + } + + @Test + public void remove() { + add(); + Assert.assertEquals(5, list.remove(6)); + Assert.assertEquals(6, list.size()); + } + + @Test + public void get() { + add(); + Assert.assertEquals(5, list.get(6)); + } + + @Test + public void testIterator() { + for (int i = 0; i < 10; i++) { + Assert.assertTrue(list.add(i)); + } + Iterator iter = list.iterator(); + int count = 0; + while(iter.hasNext()) { + Assert.assertEquals(count, iter.next()); + count++; + } + } + +} diff --git a/group11/1178243325/week01/src/test/java/com/sprint/basic/queue/QueueTest.java b/group11/1178243325/week01/src/test/java/com/sprint/basic/queue/QueueTest.java new file mode 100644 index 0000000000..b7cfe4b32f --- /dev/null +++ b/group11/1178243325/week01/src/test/java/com/sprint/basic/queue/QueueTest.java @@ -0,0 +1,20 @@ +package com.sprint.basic.queue; + +import org.junit.Assert; +import org.junit.Test; +public class QueueTest { + + private Queue queue = new Queue(); + + @Test + public void testQueueApi() { + Assert.assertTrue(queue.enQueue(1)); + Assert.assertTrue(queue.enQueue(2)); + Assert.assertFalse(queue.isEmpty()); + Assert.assertEquals(2, queue.size()); + Assert.assertEquals(1, queue.deQueue()); + Assert.assertEquals(2, queue.deQueue()); + Assert.assertEquals(0, queue.size()); + Assert.assertTrue(queue.isEmpty()); + } +} diff --git a/group11/1178243325/week01/src/test/java/com/sprint/basic/stack/StackTest.java b/group11/1178243325/week01/src/test/java/com/sprint/basic/stack/StackTest.java new file mode 100644 index 0000000000..e267c59971 --- /dev/null +++ b/group11/1178243325/week01/src/test/java/com/sprint/basic/stack/StackTest.java @@ -0,0 +1,23 @@ +package com.sprint.basic.stack; + +import org.junit.Assert; +import org.junit.Test; + +public class StackTest { + + private Stack stack = new Stack(); + + @Test + public void testStack() { + Assert.assertTrue(stack.push(1)); + Assert.assertEquals(1, stack.pop()); + Assert.assertTrue(stack.push(2)); + Assert.assertTrue(stack.push(3)); + Assert.assertTrue(stack.push(4)); + Assert.assertEquals(4, stack.pop()); + Assert.assertEquals(2, stack.peek()); + Assert.assertEquals(2, stack.size()); + Assert.assertFalse(stack.isEmpty()); + } + +} diff --git a/group11/1178243325/week01/src/test/java/com/sprint/basic/tree/BinaryTreeNodeTest.java b/group11/1178243325/week01/src/test/java/com/sprint/basic/tree/BinaryTreeNodeTest.java new file mode 100644 index 0000000000..d9a27ab211 --- /dev/null +++ b/group11/1178243325/week01/src/test/java/com/sprint/basic/tree/BinaryTreeNodeTest.java @@ -0,0 +1,54 @@ +package com.sprint.basic.tree; + +import org.junit.Assert; +/*参考程序*/ +public class BinaryTreeNodeTest { + + private BinaryTreeNode treeNode; + + @org.junit.Before + public void setUp() throws Exception { + treeNode = new BinaryTreeNode<>(); + treeNode.insert(5); + treeNode.insert(3); + treeNode.insert(7); + treeNode.insert(1); + treeNode.insert(4); + treeNode.insert(2); + treeNode.insert(8); + treeNode.insert(6); + } + + @org.junit.Test + public void insert() { + Assert.assertEquals(treeNode.getData().intValue(), 5); + Assert.assertEquals(treeNode.getLeft().getData(), 3); + Assert.assertEquals(treeNode.getRight().getData(), 7); + Assert.assertEquals(treeNode.getLeft().getLeft().getData(), 1); + Assert.assertEquals(treeNode.getLeft().getRight().getData(), 4); + Assert.assertEquals(treeNode.getLeft().getLeft().getRight().getData(), 2); + Assert.assertEquals(treeNode.getRight().getRight().getData(), 8); + Assert.assertEquals(treeNode.getRight().getLeft().getData(), 6); + } + + @org.junit.Test + public void delete() throws Exception { + treeNode.delete(3); + for (int i = 1; i < 9; i++) { + if (i != 3) { + Assert.assertNotNull(treeNode.search(i)); + } else { + Assert.assertNull(treeNode.search(i)); + } + } + } + + @org.junit.Test + public void search() throws Exception { + for (int i = 1; i < 9; i++) { + Assert.assertNotNull(treeNode.search(i)); + } + Assert.assertNull(treeNode.search(0)); + Assert.assertNull(treeNode.search(9)); + } +} diff --git a/group11/1178243325/week02/build.gradle b/group11/1178243325/week02/build.gradle new file mode 100644 index 0000000000..f6ebbb892e --- /dev/null +++ b/group11/1178243325/week02/build.gradle @@ -0,0 +1,12 @@ +apply plugin: 'java' + + +repositories { + maven { url "http://maven.aliyun.com/nexus/content/groups/public" } + mavenCentral() +} + +dependencies { + compile("org.jdom:jdom2:2.0.5") + testCompile("junit:junit:4.12") +} diff --git a/group11/1178243325/week02/readme.md b/group11/1178243325/week02/readme.md new file mode 100644 index 0000000000..a4f9adc15a --- /dev/null +++ b/group11/1178243325/week02/readme.md @@ -0,0 +1,23 @@ +## 讲课内容: +- 17-03-01:第一周作业讲评 +- 17-03-05:漫谈进程和线程和布置第三周作业 + +## 第二周作业(2-27 至 3-5) +- 实现第一个大作业:读取struts.xml,执行Action +- 5道数据结构习题 + +## 完成情况: +- struts大作业完成 +- 数据结构习题完成 + +## 我的收获: +- TDD +- 操作系统抽象概念 +- 进程在虚拟存储器表示 +- 进程调度 +- 进程同步 +- 线程 + + +![99.jpg](http://upload-images.jianshu.io/upload_images/2031765-d3740acf4d284e93.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) + diff --git a/group11/1178243325/week02/src/main/java/com/sprint/array/ArrayUtil.java b/group11/1178243325/week02/src/main/java/com/sprint/array/ArrayUtil.java new file mode 100644 index 0000000000..01d7d5f0da --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/array/ArrayUtil.java @@ -0,0 +1,229 @@ +package com.sprint.array; + +public class ArrayUtil { + + /** + * 给定一个整形数组a , 对该数组的值进行置换 + 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] + 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] + * @param origin + * @return + */ + public static void reverseArray(int[] origin){ + if (origin == null) { + return; + } + + int length = origin.length; + int[] temp = new int[length]; + for (int i = 0; i < length; i++) + temp[i] = origin[i]; + for (int i = length - 1, j = 0; i >= 0 && j < length; i--, j++) + origin[j] = temp[i]; + } + + /** + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: + * {1,3,4,5,6,6,5,4,7,6,7,5} + * @param oldArray + * @return + */ + + public static int[] removeZero(int[] oldArray){ + if (oldArray == null) { + return new int[0]; + } + + int zeroCount = 0; + for (int i = 0; i < oldArray.length; i++) { + if (oldArray[i] == 0) + zeroCount++; + } + int[] newArray = new int[oldArray.length-zeroCount]; + for (int i = 0, j = 0; i < oldArray.length && j < newArray.length; i++) { + if (oldArray[i] != 0) { + newArray[j] = oldArray[i]; + j++; + } + } + return newArray; + } + + /** + * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 + * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * @param array1 + * @param array2 + * @return + */ + + public static int[] merge(int[] array1, int[] array2){ + if (array1 == null && array2 == null) + return new int[0]; + int index1 = 0, index2 = 0; + int[] array3 = new int[array1.length + array2.length]; + int index = 0; + while (index1 != array1.length && index2 != array2.length) { + if (array1[index1] < array2[index2]) { + array3[index++] = array1[index1++]; + } else if (array1[index1] > array2[index2]) { + array3[index++] = array2[index2++]; + } else if (array1[index1] == array2[index2]){ + array3[index++] = array1[index1++]; + index2++; + } + } + + if (index1 == array1.length && index2 != array2.length) { + for (int i = index2; i < array2.length; i++) + array3[index++] = array2[i]; + } else if (index2 == array2.length && index1 != array1.length) { + for (int i = index1; i < array1.length; i++) { + array3[index++] = array1[i]; + } + } + + int[] newArray = new int[index]; + for (int i = 0; i < newArray.length; i++) + newArray[i] = array3[i]; + 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){ + if (size <= 0) + return new int[0]; + int[] newArray = new int[oldArray.length + size]; + for (int i = 0; i < oldArray.length; i++) { + newArray[i] = oldArray[i]; + } + return newArray; + } + + /** + * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 + * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] + * max = 1, 则返回空数组 [] + * @param max + * @return + */ + public static int[] fibonacci(int max){ + if (max < 1) + return new int[0]; + if (max == 1) + return new int[0]; + int[] array = new int[max]; + int i = 0; + int value = fibonaccis(i+1); + while ( value < max) { + array[i++] = value; + value = fibonaccis(i+1); + } + int[] newArray = new int[i]; + for (int j = 0; j < newArray.length; j++) { + newArray[j] = array[j]; + } + return newArray; + } + + private static int fibonaccis(int n) { + if (n <=0) + return 0; + if (n == 1 || n ==2 ) + return 1; + return fibonaccis(n-1)+fibonaccis(n-2); + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public static int[] getPrimes(int max){ + if (max <= 1) { + return new int[0]; + } + int[] array = new int[max]; + int index = 0; + for (int i = 2; i < max; i++) { + if (i == 2 || i == 3 || i == 5 || i == 7) + array[index++] = i; + if (i%2 !=0 && i%3 != 0 && i%5 != 0 && i%7 != 0) + array[index++] = i; + } + int[] newArray = new int[index]; + for (int i = 0; i < newArray.length; i++) { + newArray[i] = array[i]; + } + + return newArray; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public static int[] getPerfectNumbers(int max){ + if (max <= 0) + return new int[0]; + int[] array = new int[max]; + int index = 0; + for (int i = 1; i < max; i++) { + if (isPerfectNumber(i)) + array[index++] = i; + } + + int[] newArray = new int[index]; + for (int i = 0; i < newArray.length; i++) + newArray[i] = array[i]; + + return newArray; + } + + private static boolean isPerfectNumber(int n) { + int sum = 0; + int i = 1; + while (i < n) { + if (n%i == 0) + sum += i; + i++; + } + if (sum == n) + return true; + return false; + } + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public static String join(int[] array, String seperator){ + if (array == null) + return null; + StringBuilder str = new StringBuilder(); + for (int i = 0; i < array.length; i++) { + if (i == array.length-1) + str.append(array[i]); + else + str.append(array[i] + seperator); + } + return str.toString(); + } + + +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Configuration.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Configuration.java new file mode 100644 index 0000000000..0f10458fc3 --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Configuration.java @@ -0,0 +1,86 @@ +package com.sprint.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) { + InputStream is = this.getClass().getClassLoader().getResourceAsStream(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 actionName) { + ActionConfig ac = this.actions.get(actionName); + if(ac == null) { + return null; + } + return ac.getClassName(); + } + + public String getResultView(String actionName, String resultName) { + ActionConfig ac = this.actions.get(actionName); + if (ac == null) { + return null; + } + return ac.getViewName(resultName); + } + private static class ActionConfig { + String name; + String clzName; + Map viewResult = new HashMap<>(); + + public ActionConfig(String actionName, String clzName) { + this.name = actionName; + this.clzName = clzName; + } + + public String getClassName() { + return clzName; + } + + public void addViewResult(String name, String viewName) { + viewResult.put(name, viewName); + } + + public String getViewName(String resultName) { + return viewResult.get(resultName); + } + } +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ConfigurationException.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..25c6784f43 --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ConfigurationException.java @@ -0,0 +1,18 @@ +package com.sprint.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/group11/1178243325/week02/src/main/java/com/sprint/litestruts/LoginAction.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/LoginAction.java new file mode 100644 index 0000000000..4b4f2b8e38 --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/LoginAction.java @@ -0,0 +1,40 @@ +package com.sprint.litestruts; + +/** + * 这是一个展示业务逻辑的类,其中用户名是硬编码 + * @author xingzhaohu + */ + +public class LoginAction { + private String name; + private String password; + private String message; + + public String execute() { + if ("test".equals(name) && "1234".equals(password)) { + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + public void setName(String name) { + this.name = name; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String getMessage() { + return message; + } +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtil.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..822355655b --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtil.java @@ -0,0 +1,70 @@ +package com.sprint.litestruts; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + return getMethods(clz, "set"); + } + + public static List getGetterMethods(Class clz) { + return getMethods(clz, "get"); + } + + 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 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 e) { + throw new ReflectionUtilException(e); + } catch (IllegalArgumentException e) { + throw new ReflectionUtilException(e); + } catch (InvocationTargetException e) { + throw new ReflectionUtilException(e); + } + } + } + } + + } + + 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 e) { + throw new ReflectionUtilException(e); + } catch (IllegalArgumentException e) { + throw new ReflectionUtilException(e); + } catch (InvocationTargetException e) { + throw new ReflectionUtilException(e); + } + } + return params; + } + +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtilException.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtilException.java new file mode 100644 index 0000000000..65cbfdf322 --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/ReflectionUtilException.java @@ -0,0 +1,20 @@ +package com.sprint.litestruts; + +import java.lang.reflect.InvocationTargetException; +public class ReflectionUtilException extends RuntimeException { + + public ReflectionUtilException(String msg) { + super(msg); + } + public ReflectionUtilException(IllegalAccessException e) { + super(e); + } + + public ReflectionUtilException(IllegalArgumentException e) { + super(e); + } + + public ReflectionUtilException(InvocationTargetException e) { + super(e); + } +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Struts.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Struts.java new file mode 100644 index 0000000000..bff4dec33b --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/Struts.java @@ -0,0 +1,53 @@ +package com.sprint.litestruts; + +import java.lang.reflect.Method; +import java.util.Map; +public class Struts { + private final static Configuration cfg = new Configuration("struts.xml"); + public static View runAction(String actionName, Map parameters) { + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + + String clzName = cfg.getClassName(actionName); + if (clzName == null) { + return null; + } + + try { + Class clz = Class.forName(clzName); + Object action = clz.newInstance(); + + ReflectionUtil.setParameters(action, parameters); + + Method m = clz.getDeclaredMethod("execute"); + String resultName = (String)m.invoke(action); + + Map params = ReflectionUtil.getParameterMap(action); + String resultView = cfg.getResultView(actionName, resultName); + View view = new View(); + view.setParameters(params); + view.setJsp(resultView); + return view; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/group11/1178243325/week02/src/main/java/com/sprint/litestruts/View.java b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/View.java new file mode 100644 index 0000000000..fb380de515 --- /dev/null +++ b/group11/1178243325/week02/src/main/java/com/sprint/litestruts/View.java @@ -0,0 +1,24 @@ +package com.sprint.litestruts; + +import java.util.Map; +public class View { + private String jsp; + private Map parameters; + + public void setJsp(String jsp) { + this.jsp = jsp; + } + + public String getJsp() { + return jsp; + } + + public void setParameters(Map parameters) { + this.parameters = parameters; + } + + public Map getParameters() { + return parameters; + } + +} diff --git a/group11/1178243325/week02/src/main/resources/struts.xml b/group11/1178243325/week02/src/main/resources/struts.xml new file mode 100644 index 0000000000..c82c7d1574 --- /dev/null +++ b/group11/1178243325/week02/src/main/resources/struts.xml @@ -0,0 +1,12 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + + diff --git a/group11/1178243325/week02/src/test/java/com/sprint/array/ArrayUtilTest.java b/group11/1178243325/week02/src/test/java/com/sprint/array/ArrayUtilTest.java new file mode 100644 index 0000000000..9cba21f7cf --- /dev/null +++ b/group11/1178243325/week02/src/test/java/com/sprint/array/ArrayUtilTest.java @@ -0,0 +1,76 @@ +package com.sprint.array; + +import java.util.Arrays; +import org.junit.Assert; +import org.junit.Test; +public class ArrayUtilTest { + + @Test + public void testReverseArray() { + int[] a = new int[]{7, 9, 30, 3}; + int[] expected = new int[]{3, 30, 9, 7}; + ArrayUtil.reverseArray(a); + Assert.assertArrayEquals(a, expected); + a = new int[]{7, 9, 30, 3, 4}; + expected = new int[]{4, 3, 30, 9, 7}; + ArrayUtil.reverseArray(a); + Assert.assertArrayEquals(a, expected); + } + + @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[] expected = new int[]{1,3,4,5,6,6,5,4,7,6,7,5}; + Assert.assertArrayEquals(ArrayUtil.removeZero(oldArr), expected); + oldArr = new int[]{1, 0, 2, 0, 3, 0}; + expected = new int[]{1, 2, 3}; + Assert.assertArrayEquals(ArrayUtil.removeZero(oldArr), expected); + } + + @Test + public void testMerge() { + int[] a1 = {3, 5, 7, 8}; + int[] a2 = {4, 5, 6, 7}; + int[] a3 = {3, 4, 5, 6, 7, 8}; + Assert.assertArrayEquals(ArrayUtil.merge(a1, a2), a3); + } + + @Test + public void testGrow() { + int[] oldArray = new int[]{2, 3, 6}; + int[] expected = new int[]{2, 3, 6, 0, 0, 0}; + Assert.assertArrayEquals(ArrayUtil.grow(oldArray, 3), expected); + } + + @Test + public void testFibonacci() { + int[] expected = new int[]{1, 1, 2, 3, 5, 8, 13}; + Assert.assertArrayEquals(ArrayUtil.fibonacci(15), expected); + expected = new int[0]; + Assert.assertArrayEquals(ArrayUtil.fibonacci(1), expected); + /*GET 新技能: [] == new int[0]*/ + System.out.println(Arrays.toString(expected)); + } + + @Test + public void testGetPrimes() { + int[] expected = new int[]{2,3,5,7,11,13,17,19}; + Assert.assertArrayEquals(ArrayUtil.getPrimes(23), expected); + } + + @Test + public void testGetPerfectNumbers() { + int[] result = new int[]{6}; + int length = ArrayUtil.getPerfectNumbers(7).length; + System.out.println(length); + Assert.assertArrayEquals(ArrayUtil.getPerfectNumbers(7), result); + } + + @Test + public void tetJoin() { + String result = "3-8-9"; + int[] array = {3, 8, 9}; + Assert.assertEquals(ArrayUtil.join(array, "-"), result); + } + +} diff --git a/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ConfigurationTest.java b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..f4b5f91668 --- /dev/null +++ b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ConfigurationTest.java @@ -0,0 +1,31 @@ +package com.sprint.litestruts; + +import org.junit.Test; +import org.junit.Assert; +public class ConfigurationTest { + Configuration cfg = new Configuration("struts.xml"); + + @Test + public void testGetClassName() { + String clzName = cfg.getClassName("login"); + Assert.assertEquals("com.sprint.litestruts.LoginAction", clzName); + clzName = cfg.getClassName("logout"); + Assert.assertEquals("com.sprint.litestruts.LoginAction", 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/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ReflectionUtilTest.java b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..c6fb04bda6 --- /dev/null +++ b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/ReflectionUtilTest.java @@ -0,0 +1,92 @@ +package com.sprint.litestruts; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Set; +import java.util.Map; + + +import org.junit.Test; +import org.junit.Assert; +public class ReflectionUtilTest { + + @Test + public void testGetSetterMethod() throws Exception{ + String name = "com.sprint.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getSetterMethods(clz); + + Assert.assertEquals(2, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("setName"); + expectedNames.add("setPassword"); + + Set acctualNames = new HashSet<>(); + for (Method m : methods) { + acctualNames.add(m.getName()); + } + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testGetGetterMethod() throws Exception { + String name = "com.sprint.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getGetterMethods(clz); + + Assert.assertEquals(3, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("getName"); + expectedNames.add("getPassword"); + expectedNames.add("getMessage"); + + Set acctualNames = new HashSet<>(); + for (Method m : methods) { + acctualNames.add(m.getName()); + } + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testSetParameters() throws Exception { + String name = "com.sprint.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 testGetParameters() throws Exception { + String name = "com.sprint.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/group11/1178243325/week02/src/test/java/com/sprint/litestruts/StrutsTest.java b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/StrutsTest.java new file mode 100644 index 0000000000..d8c68d2807 --- /dev/null +++ b/group11/1178243325/week02/src/test/java/com/sprint/litestruts/StrutsTest.java @@ -0,0 +1,32 @@ +package com.sprint.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/group11/1178243325/week03/build.gradle b/group11/1178243325/week03/build.gradle new file mode 100644 index 0000000000..c4da624f95 --- /dev/null +++ b/group11/1178243325/week03/build.gradle @@ -0,0 +1,9 @@ +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + testCompile("junit:junit:4.12") +} diff --git a/group11/1178243325/week03/readme.md b/group11/1178243325/week03/readme.md new file mode 100644 index 0000000000..5de5dada98 --- /dev/null +++ b/group11/1178243325/week03/readme.md @@ -0,0 +1,16 @@ +## 讲课内容: +- 17-03-07:答疑(YY) +- 17-03-09:TDD和第二次作业讲解 +- 17-03-12:职场15年 + +## 第三周作业(3-6 至 3-12) +- 实现第二个大作业:多线程下载文件,支持断点续传 +- 5道数据结构习题 + +## 完成情况: +- 多线程完成 +- 待重构 + +## 我的收获: +- TTD大法好 +- 面向对象的思想以及抽象化,更深刻 diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/Iterator.java b/group11/1178243325/week03/src/main/java/com/sprint/basic/Iterator.java similarity index 100% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/Iterator.java rename to group11/1178243325/week03/src/main/java/com/sprint/basic/Iterator.java diff --git a/group11/1178243325/week03/src/main/java/com/sprint/basic/LinkedList.java b/group11/1178243325/week03/src/main/java/com/sprint/basic/LinkedList.java new file mode 100644 index 0000000000..ac4128fe80 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/basic/LinkedList.java @@ -0,0 +1,319 @@ +package com.sprint.basic; + +import com.sprint.basic.exception.ConcurrentModificationException; +import java.util.Objects; +public class LinkedList implements List { + + private Node head; + private int size; + public LinkedList() { + head = new Node(null, null); + size = 0; + } + + public void add(Object o){ + add(size, o); + } + + public void add(int index , Object o){ + if (index > size || index < 0) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + Node frontNode = getNode(index-1); + Node newNode = new Node(o, frontNode.next); + frontNode.next = newNode; + size++; + + } + + /*getNode getPreNodeByElement getNextNodeByElement的效率低些*/ + private Node getNode(int index) { + Node node = head; + int i = 0; + while(node.next != null && i <= index) { + node = node.next; + i++; + } + return node; + } + + private Node getPreNodeByElement(Object obj) { + if (obj != null) { + for (int i = 0; i < size(); i++) { + if (getNode(i).data == obj) { + return getNode(i-1); + } + } + } + return null; + } + + private Node getNextNodeByElement(Object obj) { + if (obj != null) { + for (int i = 0; i < size(); i++) { + if (getNode(i).data == obj) { + return getNode(i+1); + } + } + } + return null; + } + public Object get(int index){ + if (index >= size || index < 0) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + + Node node = getNode(index); + return node.data; + } + + public Object remove(int index){ + if (index >= size || index < 0) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + Node frontNode = getNode(index-1); + Node oldNode = getNode(index); + frontNode.next = oldNode.next; + size--; + return oldNode.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(); + } + + private class LinkedListIterator implements Iterator { + int index; + final int capacity = size; + LinkedListIterator() { + index = 0; + } + @Override + public boolean hasNext() { + if (capacity != size) + throw new ConcurrentModificationException("此对象没有修改同步"); + return index < capacity; + } + + @Override + public Object next() { + if (capacity != size) + throw new ConcurrentModificationException("此对象没有修改同步"); + if (index >= capacity) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + return get(index++); + } + } + + private String outOfBoundsMsg(int index) { + return "index:" + index + ", size:" + size; + } + + private static class Node { + Object data; + Node next; + + Node(Object data, Node next) { + this.data = data; + this.next = next; + } + + void setData(Object data) { + this.data = data; + } + + Object getData() { + return data; + } + + void setNext(Node next) { + this.next = next; + } + + Object getNext() { + return next; + } + } + + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + Object[] oldData = new Object[size]; + Node temp = head; + int index = 1; + while(temp.next != null) { + temp = temp.next; + oldData[size - index] = temp.data; + index++; + } + + index = 0; + temp = head; + while(temp.next != null) { + temp = temp.next; + temp.data = oldData[index]; + index++; + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + + public void removeFirstHalf(){ + int count = size; + if (count % 2 != 0) { + for (int i = 0; i <= count/2; i++) { + removeFirst(); + } + } else { + for (int i = 0; i < count/2; i++) { + removeFirst(); + } + } + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + + public void remove(int i, int length){ + if (i < 0 || length < 0) { + return; + } + if (i == 0) { + for (int k = 0; k < length; k++) + removeFirst(); + } else { + while (length > 0) { + remove(i-1); + length--; + } + } + } + + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + + public int[] getElements(LinkedList list){ + if (list.size() == 0) { + return new int[0]; + } + int[] array = new int[list.size()]; + int index = 0; + for (int i = 0; i < list.size(); i++) { + array[i] = (int)get((int)list.get(i)); + } + return array; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + * @param list + */ + public void subtract(LinkedList list){ + if (list.size() == 0) { + return; + } + for (int i = 0; i < list.size(); i++) { + removeElement(list.get(i)); + } + } + + private Object removeElement(Object obj) { + if (obj == null) { + return null; + } + Node preNode = getPreNodeByElement(obj); + Node nextNode = getNextNodeByElement(obj); + if (preNode == null && nextNode == null) + return null; + preNode.next = nextNode; + return obj; + } + + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + + 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){ + } + + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + + public LinkedList intersection( LinkedList list){ + + return null; + + } +} diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/List.java b/group11/1178243325/week03/src/main/java/com/sprint/basic/List.java similarity index 100% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/List.java rename to group11/1178243325/week03/src/main/java/com/sprint/basic/List.java diff --git a/group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/ConcurrentModificationException.java b/group11/1178243325/week03/src/main/java/com/sprint/basic/exception/ConcurrentModificationException.java similarity index 100% rename from group11/1178243325/DataStructure/src/main/java/com/coding/basic/exception/ConcurrentModificationException.java rename to group11/1178243325/week03/src/main/java/com/sprint/basic/exception/ConcurrentModificationException.java diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/DownloadThread.java b/group11/1178243325/week03/src/main/java/com/sprint/download/DownloadThread.java new file mode 100644 index 0000000000..434b60e7be --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/DownloadThread.java @@ -0,0 +1,36 @@ +package com.sprint.download; + +import com.sprint.download.api.Connection; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; +public class DownloadThread extends Thread { + Connection conn; + int startPos; + int endPos; + CyclicBarrier barrier; + String localFile; + public DownloadThread(Connection conn, int startPos, int endPos, + String localFile, CyclicBarrier barrier) { + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.localFile = localFile; + this.barrier = barrier; + } + + @Override + public void run() { + try { + System.out.println("Begin to read [" + startPos + "-" + endPos + "]"); + byte[] data = conn.read(startPos, endPos); + RandomAccessFile file = new RandomAccessFile(localFile, "rw"); + file.seek(startPos); + file.write(data); + file.close(); + conn.close(); + barrier.await(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/FileDownloader.java b/group11/1178243325/week03/src/main/java/com/sprint/download/FileDownloader.java new file mode 100644 index 0000000000..9a817aefaf --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/FileDownloader.java @@ -0,0 +1,89 @@ +package com.sprint.download; + +import com.sprint.download.api.Connection; +import com.sprint.download.api.ConnectionManager; +import com.sprint.download.api.DownloadListener; +import java.util.concurrent.CyclicBarrier; +import java.io.RandomAccessFile; +import java.io.IOException; +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() { + CyclicBarrier barrier = new CyclicBarrier(DOWNLOAD_THREAD_NUM, new Runnable() { + public void run() { + listener.notifyFinished(); + } + }); + + Connection conn = null; + + try { + conn = cm.open(this.url); + int length = conn.getContentLength(); + createPlaceHolderFile(this.localFile, length); + int[][] ranges = allocateDownloadRange(DOWNLOAD_THREAD_NUM, length); + for (int i = 0; i < DOWNLOAD_THREAD_NUM; i++) { + DownloadThread thread = new DownloadThread( + cm.open(url), + ranges[i][0], + ranges[i][1], + localFile, + barrier); + thread.start(); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (conn != null) { + conn.close(); + } + } + } + + private void createPlaceHolderFile(String fileName, int contentLen) throws IOException { + RandomAccessFile file = new RandomAccessFile(fileName, "rw"); + for (int i = 0; i < contentLen; i++) { + file.write(0); + } + file.close(); + } + + private int[][] allocateDownloadRange(int threadNum, int contentLen) { + int[][] ranges = new int[threadNum][2]; + int eachThreadSize = contentLen / threadNum; + int left = contentLen % threadNum; + for (int i = 0; i < threadNum; i++) { + int startPos = i*eachThreadSize; + int endPos = (i+1) * eachThreadSize - 1; + if (i == (threadNum -1)) { + endPos += left; + } + ranges[i][0] = startPos; + ranges[i][1] = endPos; + } + return ranges; + } + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm) { + this.cm = ucm; + } + + public DownloadListener getListener() { + return listener; + } +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/api/Connection.java b/group11/1178243325/week03/src/main/java/com/sprint/download/api/Connection.java new file mode 100644 index 0000000000..958a0b1ce3 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/api/Connection.java @@ -0,0 +1,26 @@ +package com.sprint.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/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionException.java b/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionException.java new file mode 100644 index 0000000000..f9ec627440 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionException.java @@ -0,0 +1,7 @@ +package com.sprint.download.api; + +public class ConnectionException extends Exception { + public ConnectionException(Exception e) { + super(e); + } +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionManager.java b/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionManager.java new file mode 100644 index 0000000000..f20bbacc87 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/api/ConnectionManager.java @@ -0,0 +1,11 @@ +package com.sprint.download.api; + +public interface ConnectionManager { + /** + * 给定一个url, 打开一个连接 + * @param url + * @return + */ + + public Connection open(String url) throws ConnectionException; +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/api/DownloadListener.java b/group11/1178243325/week03/src/main/java/com/sprint/download/api/DownloadListener.java new file mode 100644 index 0000000000..fc95ba8199 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.sprint.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionImpl.java b/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..c6c1f32cb4 --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionImpl.java @@ -0,0 +1,68 @@ +package com.sprint.download.impl; + +import com.sprint.download.api.Connection; +import com.sprint.download.api.ConnectionException; +import java.util.Arrays; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.HttpURLConnection; + +public class ConnectionImpl implements Connection { + + URL url; + static final int BUFFER_SIZE = 1024; + + ConnectionImpl(String _url) throws ConnectionException { + try { + url = new URL(_url); + } catch (MalformedURLException e) { + throw new ConnectionException(e); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + HttpURLConnection httpConn = (HttpURLConnection)url.openConnection(); + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + InputStream is = httpConn.getInputStream(); + byte[] buff = new byte[BUFFER_SIZE]; + int totalLen = endPos - startPos + 1; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + while (baos.size() < totalLen) { + int len = is.read(buff); + if (len < 0) { + break; + } + baos.write(buff, 0, len); + } + + if (baos.size() > totalLen) { + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + URLConnection con; + try { + con = url.openConnection(); + return con.getContentLength(); + } catch (IOException e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + + } +} diff --git a/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionManagerImpl.java b/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..7a012808ef --- /dev/null +++ b/group11/1178243325/week03/src/main/java/com/sprint/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,14 @@ +package com.sprint.download.impl; + +import com.sprint.download.api.Connection; +import com.sprint.download.api.ConnectionException; +import com.sprint.download.api.ConnectionManager; +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } +} + + diff --git a/group11/1178243325/week03/src/test/java/com/sprint/download/FileDownloaderTest.java b/group11/1178243325/week03/src/test/java/com/sprint/download/FileDownloaderTest.java new file mode 100644 index 0000000000..6e3bccd2dc --- /dev/null +++ b/group11/1178243325/week03/src/test/java/com/sprint/download/FileDownloaderTest.java @@ -0,0 +1,41 @@ +package com.sprint.download; + +import com.sprint.download.api.ConnectionManager; +import com.sprint.download.api.DownloadListener; +import com.sprint.download.impl.ConnectionManagerImpl; + +import org.junit.Assert; +import org.junit.Test; +public class FileDownloaderTest { + boolean downloadFinished = false; + + @Test + public void testDownload() { + String url = "http://images2015.cnblogs.com/blog/610238/201604/610238-20160421154632101-286208268.png"; + FileDownloader downloader = new FileDownloader(url, "/home/sprint/xxx/test.jpg");// 保存地址时我的本地地址 + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = false; + } + }); + + downloader.execute(); + + //等待多线程下载 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + } +} diff --git a/group11/1178243325/week03/src/test/java/com/sprint/download/api/ConnectionTest.java b/group11/1178243325/week03/src/test/java/com/sprint/download/api/ConnectionTest.java new file mode 100644 index 0000000000..4322814936 --- /dev/null +++ b/group11/1178243325/week03/src/test/java/com/sprint/download/api/ConnectionTest.java @@ -0,0 +1,21 @@ +package com.sprint.download.api; + +import com.sprint.download.impl.ConnectionManagerImpl; +import org.junit.Assert; +import org.junit.Test; +public class ConnectionTest { + + @Test + public void testGetContentLength() throws Exception { + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"); + Assert.assertEquals(35470, conn.getContentLength()); + } + + @Test + public void testRead() throws Exception { + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"); + + } +} diff --git a/group11/1178243325/week04/readme.md b/group11/1178243325/week04/readme.md new file mode 100644 index 0000000000..2199199aef --- /dev/null +++ b/group11/1178243325/week04/readme.md @@ -0,0 +1,12 @@ +## 讲课内容: +- 17-03-15:第三次作业讲解 +- 17-03-19:Edison分享的职业发展 + +## 第四周作业(3-13 至 3-19) +无,调整进度 + +## 完成情况: +休养生息 + +## 我的收获: +- 职业发展:从新人到老兵 diff --git a/group11/1178243325/week05/readme.md b/group11/1178243325/week05/readme.md new file mode 100644 index 0000000000..d4388e66d7 --- /dev/null +++ b/group11/1178243325/week05/readme.md @@ -0,0 +1,13 @@ +## 讲课内容: +- 17-03-22 :漫谈操作系统之虚拟内存 +- 17-03-26 :概要性介绍class文件结构和字节码的执行过程 + +## 第五周作业(3-20 至 3-26) +无,调整进度 + +## 完成情况: +修养生息 + +## 我的收获: +- 虚拟内存 +- 进一步理解JVM diff --git a/group11/1178243325/week06/build.gradle b/group11/1178243325/week06/build.gradle new file mode 100644 index 0000000000..128f6fda07 --- /dev/null +++ b/group11/1178243325/week06/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + compile("commons-io:commons-io:2.4") + //compile("commons-lang:commons-lang:2.6") + compile("org.apache.commons:commons-lang3:3.4") + testCompile("junit:junit:4.12") +} + diff --git a/group11/1178243325/week06/readme.md b/group11/1178243325/week06/readme.md new file mode 100644 index 0000000000..d89a5c904e --- /dev/null +++ b/group11/1178243325/week06/readme.md @@ -0,0 +1,16 @@ +## 讲课内容: +- 17-03-27:JVM第一周 +- 17-03-29:JVM之classLoader + +## 第六周作业(3-27 至 04-02) +- 完成对一个.class文件的读取和对.class文件开头四个字节的魔数的判断需要实现ClassLoader.java +- 实现LRU算法 +- 一篇文章 + +## 完成情况: +- ClassLoader.java已完 +- LRU已完 +- [文章](http://www.jianshu.com/p/02a8b4ee4596) + +## 我的收获: +使用开源工具读取文件,并利用工作类进行字符转换.LRU算法(双链表操作),但是更重要的抽象化思想. diff --git a/group11/1178243325/week06/src/main/java/com/sprint/basic/LRUPageFrame.java b/group11/1178243325/week06/src/main/java/com/sprint/basic/LRUPageFrame.java new file mode 100644 index 0000000000..0a2febd715 --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/basic/LRUPageFrame.java @@ -0,0 +1,117 @@ +package com.sprint.basic; + +public class LRUPageFrame { + + /** + * 用双向链表实现LRU算法 + */ + + private static class Node { + Node prev; + Node next; + int pageNum; + + Node() { + + } + } + + private int capacity; + private int currentSize; + private Node first; + private Node last; + + public LRUPageFrame(int capacity) { + this.currentSize = 0; + this.capacity = capacity; + } + + /** + * + */ + public void access(int pageNum) { + Node node = find(pageNum); + if (node != null) { + moveExistingNodeToHead(node); + } else { + node = new Node(); + node.pageNum = pageNum; + if (currentSize >= capacity) { + removeLast(); + } + addNewNodeToHead(node); + } + } + + private Node find(int pageNum) { + Node node = first; + while (node != null) { + if (node.pageNum == pageNum) { + return node; + } + node = node.next; + } + return null; + } + + private void moveExistingNodeToHead(Node node) { + if (node == first) { + return; + } else if (node == last) { + Node prevNode = node.prev; + prevNode.next = null; + last.prev = null; + last = prevNode; + } else { + Node prevNode = node.prev; + prevNode.next = node.next; + Node nextNode = node.next; + nextNode.prev = prevNode; + } + + node.prev = null; + node.next = first; + first.prev = node; + first = node; + } + + private void removeLast() { + Node prev = last.prev; + prev.next = null; + last.prev = null; + last = prev; + this.currentSize--; + } + + private void addNewNodeToHead(Node node) { + if (isEmpty()) { + node.prev = null; + node.next = null; + first = node; + last = node; + } else { + node.prev = null; + node.next = first; + first.prev = node; + first = node; + } + this.currentSize++; + } + + private boolean isEmpty() { + return (first == null) && (last == null); + } + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + Node node = first; + while (node != null) { + buffer.append(node.pageNum); + node = node.next; + if (node != null) { + buffer.append(","); + } + } + return buffer.toString(); + } +} diff --git a/group11/1178243325/week06/src/main/java/com/sprint/jvm/clz/ClassFile.java b/group11/1178243325/week06/src/main/java/com/sprint/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..c40c88b183 --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/jvm/clz/ClassFile.java @@ -0,0 +1,9 @@ +package com.sprint.jvm.clz; + +public class ClassFile { + private final String cafebabe = "cafebabe"; + + public String getCafebabe() { + return cafebabe; + } +} diff --git a/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..445519b3be --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,17 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.util.Util; +import java.util.Arrays; +public class ByteCodeIterator { + byte[] codes; + int pos = 0; + ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public String nextU4ToHexString() { + return Util.byteToHexString(new byte[] {codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + +} diff --git a/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..1191be47eb --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java @@ -0,0 +1,49 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.clz.ClassFile; +import java.io.IOException; +import java.io.File; +import java.io.FileInputStream; +import java.util.List; +import java.util.ArrayList; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +public class ClassFileLoader { + List clzPaths = new ArrayList<>(); + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + } + + public void addClassPath(String clzPath) { + if (this.clzPaths.contains(clzPath)) { + return; + } + this.clzPaths.add(clzPath); + } + + private byte[] readBinaryCode(String className) { + className = className.replace('.', File.separatorChar) + ".class"; + for (String path : clzPaths) { + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if (codes != null) { + return codes; + } + } + return null; + } + + private byte[] loadClassFile(String clzFileName) { + File f = new File(clzFileName); + try { + return IOUtils.toByteArray(new FileInputStream(f)); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileParser.java b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..229e7db360 --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/jvm/loader/ClassFileParser.java @@ -0,0 +1,14 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.clz.ClassFile; +public class ClassFileParser { + public ClassFile parse(byte[] codes) { + ClassFile clzFile = new ClassFile(); + ByteCodeIterator iter = new ByteCodeIterator(codes); + String magicNumber = iter.nextU4ToHexString(); + if (!"cafebabe".equals(magicNumber)) { + return null; + } + return clzFile; + } +} diff --git a/group11/1178243325/week06/src/main/java/com/sprint/jvm/util/Util.java b/group11/1178243325/week06/src/main/java/com/sprint/jvm/util/Util.java new file mode 100644 index 0000000000..6081635316 --- /dev/null +++ b/group11/1178243325/week06/src/main/java/com/sprint/jvm/util/Util.java @@ -0,0 +1,17 @@ +package com.sprint.jvm.util; + +public class Util { + public static String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group11/1178243325/week06/src/test/java/com/sprint/basic/LRUPageFrameTest.java b/group11/1178243325/week06/src/test/java/com/sprint/basic/LRUPageFrameTest.java new file mode 100644 index 0000000000..ac28668dbe --- /dev/null +++ b/group11/1178243325/week06/src/test/java/com/sprint/basic/LRUPageFrameTest.java @@ -0,0 +1,33 @@ +package com.sprint.basic; +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + frame.access(5); + Assert.assertEquals("5,4,0", frame.toString()); + + } + +} diff --git a/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java b/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java new file mode 100644 index 0000000000..d3d84b414f --- /dev/null +++ b/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java @@ -0,0 +1,23 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.clz.ClassFile; +import org.junit.Test; +import org.junit.Assert; +public class ClassFileLoaderTest { + + private static final String FULL_QUALTFIED_CLASS_NAME = "com/sprint/jvm/EmployeeV1"; + + static String path1 = "/home/sprint/java/code/coding2017/group11/1178243325/week06/build/classes/test"; + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.sprint.jvm.loader.EmployeeV1"; + clzFile = loader.loadClass(className); + } + + @Test + public void test() { + Assert.assertEquals("cafebabe", clzFile.getCafebabe()); + } +} diff --git a/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/EmployeeV1.java b/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/EmployeeV1.java new file mode 100644 index 0000000000..6b8532842b --- /dev/null +++ b/group11/1178243325/week06/src/test/java/com/sprint/jvm/loader/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.sprint.jvm.loader; + +public class EmployeeV1 { + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello, this is class Employee"); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 20); + p.sayHello(); + } +} diff --git a/group11/1178243325/week07/.readme.md.swp b/group11/1178243325/week07/.readme.md.swp new file mode 100644 index 0000000000..3d7e4464a8 Binary files /dev/null and b/group11/1178243325/week07/.readme.md.swp differ diff --git a/group11/1178243325/week07/build.gradle b/group11/1178243325/week07/build.gradle new file mode 100644 index 0000000000..128f6fda07 --- /dev/null +++ b/group11/1178243325/week07/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + compile("commons-io:commons-io:2.4") + //compile("commons-lang:commons-lang:2.6") + compile("org.apache.commons:commons-lang3:3.4") + testCompile("junit:junit:4.12") +} + diff --git a/group11/1178243325/week07/readme.md b/group11/1178243325/week07/readme.md new file mode 100644 index 0000000000..cc9d7c6f3c --- /dev/null +++ b/group11/1178243325/week07/readme.md @@ -0,0 +1,12 @@ +## 讲课内容: +- 17-03-29 :JVM之classLoader + +## 第七周作业(04-03 至 04-09) +- 实现对一个.class文件的常量池读取 +- 实现StackUtil +- [文章](http://www.jianshu.com/p/502c1e5caa97) +## 完成情况: + + +## 我的收获: + diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/AccessFlag.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..e74740aa3e --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.sprint.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flagValue) { + this.flagValue = flagValue; + } + + public boolean isPublicClass() { + return (this.flagValue & 0x0001) != 0; + } + + public boolean isFinalClass() { + return (this.flagValue & 0x0010) != 0; + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassFile.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..4e5aad16f9 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassFile.java @@ -0,0 +1,71 @@ +package com.sprint.jvm.clz; + +import com.sprint.jvm.constant.ConstantPool; +import com.sprint.jvm.constant.ClassInfo; +public class ClassFile { + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + public int getMinorVersion() { + return minorVersion; + } + + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + + public int getMajorVersion() { + return majorVersion; + } + + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + + public AccessFlag getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + public ClassIndex getClassIndex() { + return clzIndex; + } + + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + public ConstantPool getConstantPool() { + return pool; + } + + public void setConstantPool(ConstantPool pool) { + this.pool = pool; + } + + public void print() { + if (this.accessFlag.isPublicClass()) { + System.out.println("Access flag : public "); + } + System.out.println("Class Name:" + getClassName() ); + System.out.println("Super Class Name:" + getSuperClassName()); + } + + private String getClassName() { + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + + private String getSuperClassName() { + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassIndex.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..46e7443d90 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/clz/ClassIndex.java @@ -0,0 +1,22 @@ +package com.sprint.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + + public void setThisClassIndex(int index) { + this.thisClassIndex = index; + } + + public int getSuperClassIndex() { + return superClassIndex; + } + + public void setSuperClassIndex(int index) { + this.superClassIndex = index; + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ClassInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..b8da3c656d --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ClassInfo.java @@ -0,0 +1,28 @@ +package com.sprint.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index; + + public ClassInfo(ConstantPool pool) { + super(pool); + } + + public void setUtf8Index(int index) { + this.utf8Index = index; + } + + public int getUtf8Index() { + return utf8Index; + } + + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..a8db82689e --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package com.sprint.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo() {} + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantPool.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..3a35c22ce0 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/ConstantPool.java @@ -0,0 +1,28 @@ +package com.sprint.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + private List constantInfos = new ArrayList(); + + public ConstantPool() { + + } + + public void addConstantInfo(ConstantInfo info) { + this.constantInfos.add(info); + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantInfos.get(index); + } + + public String getUTF8String(int index) { + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + + public Object getSize() { + return this.constantInfos.size() - 1; + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/FieldRefInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..c0eb449085 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/FieldRefInfo.java @@ -0,0 +1,52 @@ +package com.sprint.jvm.constant; + +public class FieldRefInfo extends ConstantInfo { + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return getClassName() + ":" + typeInfo.getName() + ":" + typeInfo.getTypeInfo() + "]"; + } + + public String getClassName() { + ClassInfo classInfo = (ClassInfo)this.getConstantInfo(this.getClassInfoIndex()); + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + return utf8Info.getValue(); + } + + public String getFieldName() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/MethodRefInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..85bb5c4934 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.sprint.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + return getClassName() + ":" + this.getMethodName() + ":" + this.getParamAndReturnType(); + } + + public String getClassName() { + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} + diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NameAndTypeInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..492fd6e0db --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,52 @@ +package com.sprint.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo { + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex1() { + return index1; + } + + public void setIndex1(int index1) { + this.index1 = index1; + } + + public int getIndex2() { + return index2; + } + + public void setIndex2(int index2) { + this.index2 = index2; + } + + public String getName() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString() { + return "(" + getName() + "," + getTypeInfo() + ")"; + } + + +} + + diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NullConstantInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..f257cea240 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/NullConstantInfo.java @@ -0,0 +1,12 @@ +package com.sprint.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + public NullConstantInfo() { + + } + + @Override + public int getType() { + return -1; + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/StringInfo.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..73c58a5e71 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.sprint.jvm.constant; + +public class StringInfo extends ConstantInfo { + private int type = ConstantInfo.STRING_INFO; + private int index; + + public StringInfo(ConstantPool constantPool) { + super(constantPool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public String toString() { + return this.getConstantPool().getUTF8String(index); + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/UTF8Info.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..5516999c0e --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/constant/UTF8Info.java @@ -0,0 +1,35 @@ +package com.sprint.jvm.constant; + +public class UTF8Info extends ConstantInfo { + private int type = ConstantInfo.UTF8_INFO; + private int length; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getType() { + return type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value + "]"; + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..fc5d1b2ac2 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,50 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.util.Util; +import java.util.Arrays; +public class ByteCodeIterator { + byte[] codes; + int pos = 0; + ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public byte[] getBytes(int len) { + if (pos + len >= codes.length) { + throw new ArrayIndexOutOfBoundsException(); + } + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos += len; + return data; + } + + public int nextU1ToInt() { + return Util.byteToInt(new byte[] {codes[pos++]}); + } + + public int nextU2ToInt() { + return Util.byteToInt(new byte[] {codes[pos++], codes[pos++]}); + } + + public int nextU4ToInt() { + return Util.byteToInt(new byte[] {codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextU4ToHexString() { + return Util.byteToHexString(new byte[] {codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextUxToHexString(int len) { + byte[] tmp = new byte[len]; + for (int i = 0; i < len; i++) { + tmp[i] = codes[pos++]; + } + return Util.byteToHexString(tmp).toLowerCase(); + } + + public void back(int n) { + this.pos -= n; + } + + +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..f190f54915 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileLoader.java @@ -0,0 +1,52 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.clz.ClassFile; +import java.io.IOException; +import java.io.File; +import java.io.FileInputStream; +import java.util.List; +import java.util.ArrayList; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + public byte[] readBinaryCode(String className) { + className = className.replace('.', File.separatorChar) + ".class"; + for (String path : this.clzPaths) { + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if (codes != null) { + return codes; + } + } + return null; + } + + private byte[] loadClassFile(String clzFileName) { + File f = new File(clzFileName); + try { + return IOUtils.toByteArray(new FileInputStream(f)); + } catch(IOException e) { + e.printStackTrace(); + return null; + } + } + + public void addClassPath(String path) { + if (this.clzPaths.contains(path)) { + return; + } + this.clzPaths.add(path); + } + + public String getClassPath() { + return StringUtils.join(this.clzPaths, ";"); + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + } +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileParser.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..4b77190a04 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/loader/ClassFileParser.java @@ -0,0 +1,107 @@ +package com.sprint.jvm.loader; + +import com.sprint.jvm.clz.ClassFile; +import com.sprint.jvm.clz.AccessFlag; +import com.sprint.jvm.clz.ClassIndex; +import com.sprint.jvm.constant.ClassInfo; +import com.sprint.jvm.constant.ConstantPool; +import com.sprint.jvm.constant.FieldRefInfo; +import com.sprint.jvm.constant.NameAndTypeInfo; +import com.sprint.jvm.constant.NullConstantInfo; +import com.sprint.jvm.constant.MethodRefInfo; +import com.sprint.jvm.constant.StringInfo; +import com.sprint.jvm.constant.UTF8Info; +import java.io.UnsupportedEncodingException; +public class ClassFileParser { + public ClassFile parse(byte[] codes) { + ClassFile clzFile = new ClassFile(); + ByteCodeIterator iter = new ByteCodeIterator(codes); + String magicNumber = iter.nextU4ToHexString(); + if (!"cafebabe".equals(magicNumber)) { + return null; + } + clzFile.setMinorVersion(iter.nextU2ToInt()); + System.out.println("minor:" + clzFile.getMinorVersion()); + clzFile.setMajorVersion(iter.nextU2ToInt()); + System.out.println("marjor:" + clzFile.getMajorVersion()); + ConstantPool pool = parseConstantPool(iter); + clzFile.setConstantPool(pool); + + AccessFlag flag = parseAccessFlag(iter); + clzFile.setAccessFlag(flag); + + ClassIndex clzIndex = parseClassIndex(iter); + clzFile.setClassIndex(clzIndex); + return clzFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + AccessFlag flag = new AccessFlag(iter.nextU2ToInt()); + return flag; + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + int thisClassIndex = iter.nextU2ToInt(); + int superClassIndex = iter.nextU2ToInt(); + + ClassIndex clzIndex = new ClassIndex(); + clzIndex.setThisClassIndex(thisClassIndex); + clzIndex.setSuperClassIndex(superClassIndex); + return clzIndex; + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + int constPoolCount = iter.nextU2ToInt(); + System.out.println("Constant Pool Count :" + constPoolCount); + ConstantPool pool = new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); + for (int i = 1; i <= constPoolCount - 1; i++) { + int tag = iter.nextU1ToInt(); + if (tag == 7) { + int utf8Index = iter.nextU2ToInt(); + ClassInfo clzInfo = new ClassInfo(pool); + clzInfo.setUtf8Index(utf8Index); + pool.addConstantInfo(clzInfo); + } else if (tag == 1) { + int len = iter.nextU2ToInt(); + byte[] data = iter.getBytes(len); + String value = null; + try { + value = new String(data, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + UTF8Info utf8Str = new UTF8Info(pool); + utf8Str.setLength(len); + utf8Str.setValue(value); + pool.addConstantInfo(utf8Str); + } else if (tag == 8) { + StringInfo info = new StringInfo(pool); + info.setIndex(iter.nextU2ToInt()); + pool.addConstantInfo(info); + } else if (tag == 9) { + FieldRefInfo field = new FieldRefInfo(pool); + field.setClassInfoIndex(iter.nextU2ToInt()); + field.setNameAndTypeIndex(iter.nextU2ToInt()); + pool.addConstantInfo(field); + } else if (tag == 10) { + MethodRefInfo method = new MethodRefInfo(pool); + method.setClassInfoIndex(iter.nextU2ToInt()); + method.setNameAndTypeIndex(iter.nextU2ToInt()); + pool.addConstantInfo(method); + } else if (tag == 12) { + NameAndTypeInfo nameType = new NameAndTypeInfo(pool); + nameType.setIndex1(iter.nextU2ToInt()); + nameType.setIndex2(iter.nextU2ToInt()); + pool.addConstantInfo(nameType); + } else { + throw new RuntimeException("the constant pool tag:" + tag + "has no been implemented yet."); + } + } + System.out.println("Finished reading Constant Pool"); + return pool; + } + + +} diff --git a/group11/1178243325/week07/src/main/java/com/sprint/jvm/util/Util.java b/group11/1178243325/week07/src/main/java/com/sprint/jvm/util/Util.java new file mode 100644 index 0000000000..0f5dc89626 --- /dev/null +++ b/group11/1178243325/week07/src/main/java/com/sprint/jvm/util/Util.java @@ -0,0 +1,22 @@ +package com.sprint.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes) { + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + public static String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java b/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java new file mode 100644 index 0000000000..5cbc24577e --- /dev/null +++ b/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/ClassFileLoaderTest.java @@ -0,0 +1,181 @@ +package com.sprint.jvm.loader; + + +import com.sprint.jvm.clz.ClassFile; +import com.sprint.jvm.clz.ClassIndex; +import com.sprint.jvm.constant.*; +import org.junit.Test; +import org.junit.Assert; +public class ClassFileLoaderTest { + + private static final String FULL_QUALIFIED_CLASS_NAME = "com/sprint/jvm/loader/EmployeeV1"; + static String path1 = "/home/sprint/java/code/coding2017/group11/1178243325/week07/build/classes/test"; + static String path2 = "/home/sprint/xxx"; + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.sprint.jvm.loader.EmployeeV1"; + clzFile = loader.loadClass(className); + clzFile.print(); + } + + + @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.sprint.jvm.loader.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1050, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.sprint.jvm.loader.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClassIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + +} diff --git a/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/EmployeeV1.java b/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/EmployeeV1.java new file mode 100644 index 0000000000..6b8532842b --- /dev/null +++ b/group11/1178243325/week07/src/test/java/com/sprint/jvm/loader/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.sprint.jvm.loader; + +public class EmployeeV1 { + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello, this is class Employee"); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 20); + p.sayHello(); + } +} diff --git a/group11/1310368322/RemoteSystemsTempFiles/.project b/group11/1310368322/RemoteSystemsTempFiles/.project new file mode 100644 index 0000000000..5447a64fa9 --- /dev/null +++ b/group11/1310368322/RemoteSystemsTempFiles/.project @@ -0,0 +1,12 @@ + + + RemoteSystemsTempFiles + + + + + + + org.eclipse.rse.ui.remoteSystemsTempNature + + diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/AttributeInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..58f2190146 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/AttributeInfo.java @@ -0,0 +1,19 @@ +package com.coderising.jvm.attr; + +public abstract class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + + int attrNameIndex; + int attrLen ; + + public AttributeInfo(int attrNameIndex, int attrLen) { + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/CodeAttr.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..e07662a68b --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/CodeAttr.java @@ -0,0 +1,86 @@ +package com.coderising.jvm.attr; + +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.loader.ByteCodeIterator; + +public class CodeAttr extends AttributeInfo{ + + private int maxStack; + private int maxLocals; + private int codeLen; + private String code; + + public String getCode(){ + return code; + } + + + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + + + public CodeAttr(int attrNameIndex, int attrLen , int maxStack, int maxLocals, int codeLen,String code) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + } + + public void setLineNumberTable(LineNumberTable t) { + this.lineNumTable = t; + } + + public void setLocalVariableTable(LocalVariableTable t) { + this.localVarTable = t; + } + + private void setStackMapTable(StackMapTable t) { + this.stackMapTable = t; + + } + + public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2toInt(); + int attrLen = iter.nextU2toInt(); + int maxStack = iter.nextU2toInt(); + int max_Locals = iter.nextU2toInt(); + int codeLen = iter.nextU4toInt(); + // �������� code + String code = iter.nextUxToHexString(codeLen); + CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, max_Locals, max_Locals, code); + + int exceptionTableLen = iter.nextU2toInt(); + + if(exceptionTableLen > 0){ + String exTable = iter.nextUxToHexString(exceptionTableLen); + System.out.println("Encounted exception table, just ignore it"); + } + + int subAttributesCount = iter.nextU2toInt(); + + for(int i = 0; i < subAttributesCount; i++){ + int subAttrNameIndex = iter.nextU2toInt(); + String subAttrName = clzFile.getConstantPool().getUTF8String(subAttrNameIndex); + if(CodeAttr.LOCAL_VAR_TABLE.equalsIgnoreCase(subAttrName)){ + int subAttrLen = iter.nextU4toInt();// ���� localVariableTable ���Ե� ���� + LocalVariableTable locVarTable = LocalVariableTable.parse(iter, subAttrNameIndex, subAttrLen); + codeAttr.setLocalVariableTable(locVarTable); + }else if(CodeAttr.LINE_NUM_TABLE.equalsIgnoreCase(subAttrName)){ + int subAttrLen = iter.nextU4toInt(); + LineNumberTable lineNumTable = LineNumberTable.parse(iter, subAttrNameIndex, subAttrLen); + codeAttr.setLineNumberTable(lineNumTable); + }else if(CodeAttr.STACK_MAP_TABLE.equalsIgnoreCase(subAttrName)){ + int subAttrLen = iter.nextU4toInt(); + StackMapTable stackMapTable = StackMapTable.parse(iter); + codeAttr.setStackMapTable(stackMapTable); + }else{ + throw new RuntimeException("need code to process" + subAttrName); + } + } + + return codeAttr; + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LineNumberTable.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..24bcb25572 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LineNumberTable.java @@ -0,0 +1,52 @@ +package com.coderising.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class LineNumberTable extends AttributeInfo{ + + List items = new ArrayList();// ����кű����кܶ�ġ��кŶ�Ӧ���� + + // ������LineNumberTable��һ���ṹ�������ñ��˿��� + private static class LineNumberItem{ + int startPC;// ��¼�ֽ����к� + int lineNum;// ��¼JavaԴ������к� + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + + public void addLineNumberItem(LineNumberItem item){ + this.items.add(item); + } + + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LineNumberTable parse(ByteCodeIterator iter, int subAttrNameIndex, int subAttrLen){ + LineNumberTable lineNumTable = new LineNumberTable(subAttrNameIndex, subAttrLen); + int lineNumTableLen = iter.nextU2toInt(); + for(int i = 0; i < lineNumTableLen; i ++){ + int startPC = iter.nextU2toInt(); + int lineNum = iter.nextU2toInt(); + LineNumberItem lineNumItem = new LineNumberItem(); + lineNumItem.setStartPC(startPC); + lineNumItem.setLineNum(lineNum); + lineNumTable.addLineNumberItem(lineNumItem); + } + return lineNumTable; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableItem.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..842e1d0a96 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableItem.java @@ -0,0 +1,41 @@ +package com.coderising.jvm.attr; + +public class LocalVariableItem { + + private int startPC;// ����������ֲ��������������ڿ�ʼ��ʱ����ֽ���ƫ���� + private int length; // �ֽ���ij��� + private int nameIndex; // �ֲ��������� + private int descIndex; // �ֲ����������� + private int index; // �ֲ�������ջ֡�еľֲ��������е� slot ��λ�� + + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getNameIndex() { + return nameIndex; + } + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + public int getDescIndex() { + return descIndex; + } + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableTable.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..757f28918b --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/LocalVariableTable.java @@ -0,0 +1,41 @@ +package com.coderising.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class LocalVariableTable extends AttributeInfo{ + + List items = new ArrayList(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LocalVariableTable parse(ByteCodeIterator iter, int subAttrName, int subAttrLen){ + + LocalVariableTable locVarTable = new LocalVariableTable(subAttrName, subAttrLen); + int localVarTableLen = iter.nextU2toInt(); + for(int i = 0; i < localVarTableLen; i++){ + int startPC = iter.nextU2toInt(); + int length = iter.nextU2toInt(); + int nameIndex = iter.nextU2toInt(); + int descIndex = iter.nextU2toInt(); + int index = iter.nextU2toInt(); + LocalVariableItem locVarItem = new LocalVariableItem(); + locVarItem.setStartPC(startPC); + locVarItem.setLength(length); + locVarItem.setNameIndex(nameIndex); + locVarItem.setDescIndex(descIndex); + locVarItem.setIndex(index); + locVarTable.addLocalVariableItem(locVarItem); + } + + return locVarTable; + } + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/StackMapTable.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..9df44fb5ca --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/attr/StackMapTable.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.attr; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class StackMapTable extends AttributeInfo{ + + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.nextU2toInt(); + int len = iter.nextU4toInt(); + StackMapTable t = new StackMapTable(index,len); + + //�����StackMapTable̫�����ӣ� ���ٴ����� ֻ��ԭʼ�Ĵ������������ + String code = iter.nextUxToHexString(len); + t.setOriginalCode(code); + + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/AccessFlag.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..4e26442ed5 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/AccessFlag.java @@ -0,0 +1,26 @@ +package com.coderising.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value){ + this.flagValue = value; + } + + public int getFlagValue(){ + return flagValue; + } + + public void setFlagValue(int flag){ + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassFile.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..4492d2df9e --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,95 @@ +package com.coderising.jvm.clz; + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; + +public class ClassFile { + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag;// �ڳ�����֮�� + private ClassIndex clzIndex;// �ڷ��ʱ�־֮��, �����������������������ͽӿ����� + private ConstantPool pool; + private List fields = new ArrayList(); + private List methods = new ArrayList(); + + + public AccessFlag getAccessFlag(){ + return accessFlag; + } + + public ClassIndex getClzIndex(){ + return clzIndex; + } + + public void setClassIndex(ClassIndex clzIndex){ + this.clzIndex = clzIndex; + } + + public int getMinorVersion(){ + System.out.println(minorVersion); + return minorVersion; + } + + public void setMinorVersion(int minorVersion){ + this.minorVersion = minorVersion; + } + + public int getMajorVersion(){ + return majorVersion; + } + + public void setMajorVersion(int majorVersion){ + this.majorVersion = majorVersion; + } + + public ConstantPool getConstantPool(){ + return this.pool; + } + public void setConstantPool(ConstantPool pool){ + this.pool = pool; + } + + public void addField(Field f){ + this.fields.add(f); + } + public List getFields(){ + return this.fields; + } + public void addMethod(Method m){ + this.methods.add(m); + } + public List getMethods() { + return methods; + } + + public void print(){ + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("ClassName: " + getClassName()); + System.out.println("SuperClassName: " + getSuperClassName()); + + } + + public void setAccessFlag(AccessFlag accessFlag){ + this.accessFlag = accessFlag; + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassIndex.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..8382ef03f9 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/clz/ClassIndex.java @@ -0,0 +1,23 @@ +package com.coderising.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex(){ + System.out.println(thisClassIndex); + return thisClassIndex; + } + + public void setThisClassIndex(int thisClassIndex){ + this.thisClassIndex = thisClassIndex; + } + + public int getSuperClassIndex(){ + return superClassIndex; + } + + public void setSuperClassIndex(int superClassIndex){ + this.superClassIndex = superClassIndex; + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ClassInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..13fc4101a3 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ClassInfo.java @@ -0,0 +1,33 @@ +package com.coderising.jvm.constant; + +public class ClassInfo extends ConstantInfo{ + + private int type = ConstantInfo.CLASS_INFO;// ��ʾ�ó���Ϊ ���ӿڵķ������� + private int utf8Index;// CONSTANT_Class_info �ͳ����� �������ṹ�е� name_index�� name_index ָ��������һ�� CONSTANT_Utf8_info ���͵ij��� + + public ClassInfo(ConstantPool pool){ + super(pool); + } + + public int getUtf8Index(){ + return utf8Index; + } + + public void setUtf8Index(int utf8Index){ + this.utf8Index = utf8Index; + } + + @Override + public int getType(){ + return type; + } + + // �������� + public String getClassName(){ + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } + + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..e20be200d6 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantInfo.java @@ -0,0 +1,34 @@ +package com.coderising.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool){// ��Ϊ�����������֮��Ҫ���� + this.constantPool = pool; + } + + public abstract int getType(); + + public ConstantPool getConstantPool(){ + return constantPool; + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index);// ������õ��� ConstantInfo ���� �ı��� constantPool �е� getConstantInfo������ + // ContantInfo ���е� getConstantInfo ��������ͬ + } + + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantPool.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..82565b7f59 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/ConstantPool.java @@ -0,0 +1,31 @@ +package com.coderising.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + // �������е� ������������Ϣ + private List constantInfos = new ArrayList(); + + public ConstantPool(){ + + } + + public void addConstantInfo(ConstantInfo info){ + this.constantInfos.add(info); + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + + public String getUTF8String(int index){ + System.out.println("index: " + index); + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + + public Object getSize(){ + return constantInfos.size() - 1; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/FieldRefInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..731c35b118 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,62 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex;// ָ�� ����Ϣ������ + private int nameAndTypeIndex;// ָ����ֶ� �� ���ֺ����� ������ + + public FieldRefInfo(ConstantPool pool){ + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex(){ + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex){ + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex(){ + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex){ + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return getClassName() + " : " + typeInfo.getName() + typeInfo.getTypeInfo() + "]"; + } + + public String getClassName(){ + ClassInfo classInfo = (ClassInfo)this.getConstantInfo(this.getClassInfoIndex()); + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + return utf8Info.getValue(); + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(nameAndTypeIndex); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(nameAndTypeIndex); + return typeInfo.getTypeInfo(); + } +} + + + + + + + + + diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/MethodRefInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..49d89083fd --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,52 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo{ + + private int type = ConstantInfo.METHOD_INFO; + private int classInfoIndex;// ָ�� �����÷������������ + private int nameAndTypeIndex;// ָ������÷��� ���ƺ����͵����� + + public MethodRefInfo(ConstantPool pool){ + super(pool); + } + + @Override + public int getType() { + return type; + } + + public int getClassInfoIndex(){ + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex){ + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex(){ + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex){ + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.classInfoIndex); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.nameAndTypeIndex); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.nameAndTypeIndex); + return typeInfo.getTypeInfo(); + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NameAndTypeInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..8494e5e76a --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,52 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1;// ָ�����Ƶ����� + private int index2;// ָ������(������)������ + + public NameAndTypeInfo(ConstantPool pool){ + super(pool); + } + + public int getIndex1(){ + return index1; + } + + public void setIndex1(int index1){ + this.index1 = index1; + } + + public int getIndex2(){ + return index2; + } + + public void setIndex2(int index2){ + this.index2 = index2; + } + + @Override + public int getType(){ + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1);// �õ� �������ֶ� �� Name ������ + return utf8Info1.getValue(); // ���� ������� �� �ֶ� ��Nameֵ + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo() + ")"; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NullConstantInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..f0be39e410 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo{ + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/StringInfo.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..3ff8e9402b --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,30 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo{ + + private int type = ConstantInfo.STRING_INFO; + private int index;// ָ���ַ��������������� + + public StringInfo(ConstantPool pool){ + super(pool); + } + + + @Override + public int getType() { + return type; + } + + public int getIndex(){ + return index; + } + + public void setIndex(int index){ + this.index = index; + } + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/UTF8Info.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..6374764b5f --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,40 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + + private int type = ConstantInfo.UTF8_INFO; + private int length; + private String value; + + public UTF8Info(ConstantPool pool){ + super(pool); + } + + public int getLength(){ + return length; + } + + public void setLength(int length){ + this.length = length; + } + + @Override + public int getType() { + return type; + } + + public String getValue(){ + return value; + } + + public void setValue(String value){ + this.value = value; + } + + @Override + public String toString(){ + return "UTF8Info [type=" + type + ",length" + length + ",value" + value + ")]"; + } + + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/field/Field.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/field/Field.java new file mode 100644 index 0000000000..9e110b1867 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/field/Field.java @@ -0,0 +1,43 @@ +package com.coderising.jvm.field; + +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.loader.ByteCodeIterator; + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private ConstantPool pool; + public int getNameIndex(){ + return nameIndex; + } + public int getDescIndex(){ + return descriptorIndex; + } + public String toString(){ + return pool.getUTF8String(nameIndex) + ":" + pool.getUTF8String(descriptorIndex); + } + public Field(int accessFlag, int nameIndex, int descriptorIndex, ConstantPool pool){ + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + public static Field parse(ConstantPool pool, ByteCodeIterator iter){ + int accessFlag = iter.nextU2toInt(); + int nameIndex = iter.nextU2toInt(); + int descriptorIndex = iter.nextU2toInt(); + int attrLen = iter.nextU2toInt(); + if(attrLen > 0){ + throw new RuntimeException("Field attributes has not been implemented"); + } + Field field = new Field(accessFlag,nameIndex,descriptorIndex,pool); + + return field; + } + + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ByteCodeIterator.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..41516cd506 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,61 @@ +package com.coderising.jvm.loader; + +public class ByteCodeIterator { + + byte[] codes; + int pos;// ά��λ�� + + public ByteCodeIterator(byte[] codes){ + this.codes = codes; + } + + public int nextU1toInt(){ + return (codes[pos++] & 0xFF); + } + + public int nextU2toInt(){ + byte [] a = new byte[]{ codes[pos++], codes[pos++]}; + return (a[0]<<8) + a[1]; + } + + public int nextU4toInt(){ + byte [] a = new byte[]{ codes[pos++], codes[pos++], codes[pos++], codes[pos++]}; + return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; + } + + public byte[] getByte(int length){ + byte []a = new byte[length]; + for(int i = 0; i < length; i++){ + a[i] = codes[pos++]; + } + return a; + } + public String nextU4ToHexString(){ + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < 4; i++){ + int a = codes[pos++] & 0xFF; + String strHex = Integer.toHexString(a); + if(strHex.length() < 2){ + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + + public String nextUxToHexString(int len) { + + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < len; i++){ + int a = codes[pos++] & 0xFF; + String strHex = Integer.toHexString(a); + if(strHex.length() < 2){ + strHex = "0" + strHex; + } + buffer.append(strHex); + } + + return buffer.toString(); + + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileLoader.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..6e479bbce9 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,69 @@ +package com.coderising.jvm.loader; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.runners.Parameterized.Parameters; + +import com.coderising.jvm.clz.ClassFile; + +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + int countForClassPath = 0; + int countForReadBinaryCode = 0; + byte [] a = new byte[10000]; + + /* ��ָ��·����ȡ�������ļ����������䱣�浽һ���ֽ������У������� + * @Parameters ָ��·�� + * @�ֽ����� + */ + public byte[] readBinaryCode(String className) throws IOException{ + DataInputStream dis = new DataInputStream( + new BufferedInputStream(new FileInputStream(className))); + for(int i = 0; dis.available() != 0; i++){ + a[i] = dis.readByte(); + countForReadBinaryCode++; + } + byte []target = new byte[countForReadBinaryCode]; + System.arraycopy(a, 0, target, 0, countForReadBinaryCode); + dis.close(); + return target; + } + + public void addClassPath(String path){ + clzPaths.add(path); + countForClassPath++; + } + + public String getClassPath(){ + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < countForClassPath; i++ ){ + if(i==countForClassPath-1){ + buffer.append(clzPaths.get(i)); + }else{ + buffer.append(clzPaths.get(i)+";"); + } + } + return buffer.toString(); + } + + public ClassFile loadClass(String className) throws IOException{ + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + } + + + + + + + + + + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileParser.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..43e3796ef5 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/ClassFileParser.java @@ -0,0 +1,169 @@ +package com.coderising.jvm.loader; + +import java.io.UnsupportedEncodingException; + +import javax.management.RuntimeErrorException; + +import com.coderising.jvm.clz.AccessFlag; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.FieldRefInfo; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.NullConstantInfo; +import com.coderising.jvm.constant.StringInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; + +/* + * ����һ���ֽ����飬����������ɶ������а��������� ClassFile + */ +public class ClassFileParser { + + // ���غ����� ClassFile + public ClassFile parse(byte[] codes){ + ClassFile clzFile = new ClassFile(); + ByteCodeIterator iter = new ByteCodeIterator(codes); + String magicNumber = iter.nextU4ToHexString(); + if(!magicNumber.equals("cafebabe")){ + return null; + } + clzFile.setMinorVersion(iter.nextU2toInt()); + clzFile.setMajorVersion(iter.nextU2toInt()); + + // ��ȡ������ + ConstantPool pool = parseConstantPool(iter); + AccessFlag accessFlag = parseAccessFlag(iter); + ClassIndex clzIndex = parseClassIndex(iter); + clzFile.setAccessFlag(accessFlag); + clzFile.setClassIndex(clzIndex); + clzFile.setConstantPool(pool);// �������м��볣���� + + parseInterfaces(iter); + parseFields(clzFile,iter); + parseMethods(clzFile,iter); + + + return clzFile; + } + + + + + private AccessFlag parseAccessFlag(ByteCodeIterator iter){ + int accessFlagValue = iter.nextU2toInt(); + AccessFlag accessFlag = new AccessFlag(accessFlagValue); + accessFlag.setFlagValue(accessFlagValue); + return accessFlag; + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter){ + int thisClassIndex = iter.nextU2toInt(); + int superClassIndex = iter.nextU2toInt(); + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(thisClassIndex); + classIndex.setSuperClassIndex(superClassIndex); + return classIndex; + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter){ + + int constantPoolCount = iter.nextU2toInt(); + System.out.println("ConstantPool Count : " + constantPoolCount); + ConstantPool pool = new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); + + // ����������ӳ���������Ϣ + for(int i = 1; i <= constantPoolCount-1; i++){// JVM �涨��������Ҫ ��ȥ 1����ȥ 1����������ij������� + + int tag = iter.nextU1toInt(); + if(tag == 7){ + // ���ӿڵķ������� ClassInfo + int utf8Index = iter.nextU2toInt(); + ClassInfo clzInfo= new ClassInfo(pool);// ����һ�� ClassInfo �� ���� + clzInfo.setUtf8Index(utf8Index); + pool.addConstantInfo(clzInfo); + }else if(tag == 1){ + // UTF-8 ������ַ��� + int length = iter.nextU2toInt(); + byte data[] = iter.getByte(length); + String value = null; + try { + value = new String(data,"UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + UTF8Info utf8Info = new UTF8Info(pool); + utf8Info.setLength(length); + utf8Info.setValue(value); + pool.addConstantInfo(utf8Info); + }else if(tag == 12){ + // NameAndTypeInfo �ֶλ򷽷��IJ��ַ������� + int NameIndex = iter.nextU2toInt(); + int TypeIndex = iter.nextU2toInt(); + NameAndTypeInfo nameAndType = new NameAndTypeInfo(pool); + nameAndType.setIndex1(NameIndex); + nameAndType.setIndex2(TypeIndex); + pool.addConstantInfo(nameAndType); + }else if(tag == 9){ + // FieldRefInfo �ֶεķ������� + int classInfoIndex = iter.nextU2toInt(); + int nameAndTypeIndex = iter.nextU2toInt(); + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + fieldRefInfo.setClassInfoIndex(classInfoIndex); + fieldRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + pool.addConstantInfo(fieldRefInfo); + }else if(tag == 10){ + // MethodRefInfo ���з����ķ������� + int classInfoIndex = iter.nextU2toInt(); + int nameAndTypeIndex = iter.nextU2toInt(); + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + methodRefInfo.setClassInfoIndex(classInfoIndex); + methodRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + pool.addConstantInfo(methodRefInfo); + }else if(tag == 8){ + int stringIndex = iter.nextU2toInt();// ָ���ַ��������������� + StringInfo stringInfo = new StringInfo(pool); + stringInfo.setIndex(stringIndex); + pool.addConstantInfo(stringInfo); + }else{ + throw new RuntimeException("the constant pool tag" + tag + "has not been implemented yet"); + } + + } + return pool; + } + + private void parseInterfaces(ByteCodeIterator iter) { + int interfacesCount = iter.nextU2toInt(); + System.out.println("interfacesCount: " + interfacesCount); + if(interfacesCount > 0){ + throw new RuntimeException("interfaces has not been implemented"); + } + + } + + private void parseFields(ClassFile clzFile, ByteCodeIterator iter) { + int fieldsCount = iter.nextU2toInt(); + System.out.println("fieldsCount: " + fieldsCount); + for(int i = 0; i < fieldsCount; i++){ + Field f = Field.parse(clzFile.getConstantPool(), iter); + clzFile.addField(f); + } + + } + + private void parseMethods(ClassFile clzFile, ByteCodeIterator iter) { + int methodsCount = iter.nextU2toInt(); + System.out.println("methodsCount: " + methodsCount); + for(int i = 0; i < methodsCount; i++){ + Method m = Method.parse(clzFile, iter); + clzFile.addMethod(m); + } + + } + +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/TestJVM.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/TestJVM.java new file mode 100644 index 0000000000..735e4d1dc2 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/loader/TestJVM.java @@ -0,0 +1,7 @@ +package com.coderising.jvm.loader; + +public class TestJVM { + public static void main(String[] args) { + System.out.println("Hello"); + } +} diff --git a/group11/1310368322/src/Mini_JVM/com/coderising/jvm/method/Method.java b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/method/Method.java new file mode 100644 index 0000000000..572880f729 --- /dev/null +++ b/group11/1310368322/src/Mini_JVM/com/coderising/jvm/method/Method.java @@ -0,0 +1,68 @@ +package com.coderising.jvm.method; + +import com.coderising.jvm.attr.AttributeInfo; +import com.coderising.jvm.attr.CodeAttr; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.loader.ByteCodeIterator; + +public class Method { + + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + + private ClassFile clzFile; + + public int getNameIndex() { + return nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr code) { + this.codeAttr = code; + } + + public ClassFile getClzFile() { + return clzFile; + } + + public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) { + this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ + int accessFlag = iter.nextU2toInt(); + int nameIndex = iter.nextU2toInt(); + int descriptor = iter.nextU2toInt(); + int attrCount = iter.nextU2toInt(); + + + Method method = new Method(clzFile,accessFlag,nameIndex,descriptor); + System.out.println("attrCount: " + attrCount); + // ����method�е����� + for(int i = 0; i < attrCount; i++){ + int attrNameIndex = iter.nextU2toInt(); + String attrName = clzFile.getConstantPool().getUTF8String(attrNameIndex); + System.out.println(attrName); + if(AttributeInfo.CODE.equalsIgnoreCase(attrName)){ + CodeAttr attrCode = CodeAttr.parse(clzFile, iter); + method.setCodeAttr(attrCode); + } + + } + return method; + } +} diff --git a/group11/1310368322/src/Download/DownloadThread.java b/group11/1310368322/src/data_structure/BigHomework/Download/DownloadThread.java similarity index 100% rename from group11/1310368322/src/Download/DownloadThread.java rename to group11/1310368322/src/data_structure/BigHomework/Download/DownloadThread.java diff --git a/group11/1310368322/src/Download/FileDownloader.java b/group11/1310368322/src/data_structure/BigHomework/Download/FileDownloader.java similarity index 100% rename from group11/1310368322/src/Download/FileDownloader.java rename to group11/1310368322/src/data_structure/BigHomework/Download/FileDownloader.java diff --git a/group11/1310368322/src/Download/api/Connection.java b/group11/1310368322/src/data_structure/BigHomework/Download/api/Connection.java similarity index 100% rename from group11/1310368322/src/Download/api/Connection.java rename to group11/1310368322/src/data_structure/BigHomework/Download/api/Connection.java diff --git a/group11/1310368322/src/Download/api/ConnectionException.java b/group11/1310368322/src/data_structure/BigHomework/Download/api/ConnectionException.java similarity index 100% rename from group11/1310368322/src/Download/api/ConnectionException.java rename to group11/1310368322/src/data_structure/BigHomework/Download/api/ConnectionException.java diff --git a/group11/1310368322/src/Download/api/ConnectionManager.java b/group11/1310368322/src/data_structure/BigHomework/Download/api/ConnectionManager.java similarity index 100% rename from group11/1310368322/src/Download/api/ConnectionManager.java rename to group11/1310368322/src/data_structure/BigHomework/Download/api/ConnectionManager.java diff --git a/group05/284422826/src/com/coderising/download/api/DownloadListener.java b/group11/1310368322/src/data_structure/BigHomework/Download/api/DownloadListener.java similarity index 100% rename from group05/284422826/src/com/coderising/download/api/DownloadListener.java rename to group11/1310368322/src/data_structure/BigHomework/Download/api/DownloadListener.java diff --git a/group11/1310368322/src/Download/impl/ConnectionImpl.java b/group11/1310368322/src/data_structure/BigHomework/Download/impl/ConnectionImpl.java similarity index 100% rename from group11/1310368322/src/Download/impl/ConnectionImpl.java rename to group11/1310368322/src/data_structure/BigHomework/Download/impl/ConnectionImpl.java diff --git a/group11/1310368322/src/Download/impl/ConnectionManagerImpl.java b/group11/1310368322/src/data_structure/BigHomework/Download/impl/ConnectionManagerImpl.java similarity index 100% rename from group11/1310368322/src/Download/impl/ConnectionManagerImpl.java rename to group11/1310368322/src/data_structure/BigHomework/Download/impl/ConnectionManagerImpl.java diff --git a/group11/1310368322/src/ArrayList.java b/group11/1310368322/src/data_structure/baseDataStructure_1/ArrayList.java similarity index 100% rename from group11/1310368322/src/ArrayList.java rename to group11/1310368322/src/data_structure/baseDataStructure_1/ArrayList.java diff --git a/group11/1310368322/src/LinkedList.java b/group11/1310368322/src/data_structure/baseDataStructure_1/LinkedList.java similarity index 100% rename from group11/1310368322/src/LinkedList.java rename to group11/1310368322/src/data_structure/baseDataStructure_1/LinkedList.java diff --git a/group11/1310368322/src/ArrayUtil.java b/group11/1310368322/src/data_structure/baseDataStructure_2/ArrayUtil.java similarity index 100% rename from group11/1310368322/src/ArrayUtil.java rename to group11/1310368322/src/data_structure/baseDataStructure_2/ArrayUtil.java diff --git a/group11/1310368322/src/data_structure/baseDataStructure_3/LinkedList.java b/group11/1310368322/src/data_structure/baseDataStructure_3/LinkedList.java new file mode 100644 index 0000000000..5ea6a988be --- /dev/null +++ b/group11/1310368322/src/data_structure/baseDataStructure_3/LinkedList.java @@ -0,0 +1,162 @@ +package DataStructure_3; + +import java.util.Stack; + +import DataStructure_1.LinkedList.Node; + +public class LinkedList { + private Node head; + static int size = 0; + public void add(Object o){ + if(null == head){ + head = new Node(); + head.data = o; + head.next = null; + }else{ + Node p = head; + while(null != p.next){ + p = p.next; + } + Node newNode = new Node(); + newNode.data = o; + p.next = newNode; + newNode.next =null; + } + size++; + } + public int size(){ + return size; + } + public void add(int index,Object o){ + if(index < 0){ + throw new RuntimeException("�±겻��Ϊ����"); + } + if(index == 0){ + addFirst(o); + size++; + return; + } + if(index > size){ + throw new RuntimeException(""); + } + int i = 0; + Node p = head; + Node q = null; + + while(i!=index){ + q = p; + p = p.next; + i++; + } + Node r = new Node(); + r.data = o; + r.next =null; + q.next = r; + r.next = p; + size++; + return; + } + + public Object get(int index){ + int i = 0; + Node p = head; + while(i != index){ + p = p.next; + i++; + } + return p.data; + } + public Object remove(int index){ + if(index < 0){ + throw new RuntimeException("�±겻��Ϊ����"); + } + if(index == 1){ + size--; + return head.data; + } + int i = 0; + Node p = head; + Node q = null; + while(i != index){ + q = p; + p = p.next; + i++; + } + q.next = p.next; + size--; + return p.data; + } + public void addFirst(Object o){ + Node p = new Node(); + p.next = head; + p.data = o; + head = p; + size++; + } + public Object removeFirst(){ + head = head.next; + size--; + return null; + } + public static class Node{ + Object data; + Node next; + } + + /** + * �Ѹ��������� + * �������� 3->7->10 �����ú��Ϊ 10->7->3 + */ + public void reverse(){ + if(null == head || null == head.next){ + return; + } + Stack s = new Stack(); + Node curNode = head; + while(curNode != null){ + s.push(curNode); + Node nextNode = curNode.next; + curNode.next = null; // �����Ͽ������� + curNode = nextNode; + } + + head = s.pop(); + curNode = head; + while(!s.isEmpty()){ + Node nextNode = s.pop(); + curNode.next = nextNode; + curNode = nextNode; + } + + } + + 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(); + } + + + + + + + + + + + + + + + +} diff --git a/group11/1310368322/src/data_structure/baseDataStructure_4_LRU/LRUPageFrame.java b/group11/1310368322/src/data_structure/baseDataStructure_4_LRU/LRUPageFrame.java new file mode 100644 index 0000000000..5e860a31d7 --- /dev/null +++ b/group11/1310368322/src/data_structure/baseDataStructure_4_LRU/LRUPageFrame.java @@ -0,0 +1,143 @@ +package DataStructure_4_LRU; + +import org.junit.runners.Parameterized.Parameters; + +/* + * ��˫������ʵ��LRU�㷨 + */ +public class LRUPageFrame { + private static class Node{ + Node prev; + Node next; + int pageNum = -1;// ����ҳ + + Node(){ + + } + } + + private int capacity; + + private Node first;// ����ͷ + private Node last;// ����β + boolean tag = false; + + public LRUPageFrame(int capacity){ + this.capacity = capacity; + + for(int i = 0; i < capacity; i++){ + Node curNode = new Node(); + if(null == first){ + last = first = curNode; + }else{ + last.next = curNode; + curNode.prev = last; + last = last.next; + } + last.next = null; + } + } + public void printList(){ + Node curNode = first; + while(curNode != null){ + curNode = curNode.next; + } + } + /* + * ��ȡ�����ж��� + * @param key + * @return + */ + public void access(int pageNum){ + printList(); + Node index = findLogicPage(pageNum); + modifyPhysicalPage(index,pageNum); + } + + /* + * @param pageNum ��ʾҪ��ѯ���߼�ҳ�� + * @return ��������ҳ���ҵ�Ҫ��ѯ���߼�ҳ�棬�򷵻ظ�����ҳ�ڵ�����ã����򷵻�null + */ + public Node findLogicPage(int pageNum){ + + Node index = null; + Node curNode = first; + while(curNode != null){ + if(curNode.pageNum == pageNum){ + index = curNode; + tag = true; + } + curNode = curNode.next; + } + return index; + } + /* + * @prama index ������ ���߼�ҳ������ҳ�Ľڵ������ + */ + public void modifyPhysicalPage(Node index,int pageNum){ + push(pageNum,index); + } + /* + * @param pageNum Ҫ push���߼�ҳ�棬 Ĭ��ջ���� first, bottom ջ�� ָ����ջ�Ĵ�С + */ + public void push(int pageNum,Node bottom){ + Node index = checkWhichListNodeNotUsed(); + if(index != null){ + index.pageNum = pageNum; + return; + } + + Node lastNode; + if(null == bottom){ + lastNode = last; + }else{ + lastNode = bottom; + } + Node curNode = lastNode.prev; + while(curNode != null){ + lastNode.pageNum = curNode.pageNum; + lastNode = curNode; + curNode = curNode.prev; + } + lastNode.pageNum = pageNum; + return; + } + + /* + * @return ��������ҳ�� pageNum û�б�ʹ�õĽڵ������(����ջ���������)�����ȫ������ʹ�ã��򷵻� null + */ + public Node checkWhichListNodeNotUsed(){ + Node node = first; + Node index = null; + while(node != null){ + if(node.pageNum == -1){ + index = node; + } + node = node.next; + } + return index; + } + + public String toString(){ + StringBuffer buffer = new StringBuffer(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + + + + + + + + + +} diff --git a/group11/1310368322/src/data_structure/baseDataStructure_5_Stack/StackUtil.java b/group11/1310368322/src/data_structure/baseDataStructure_5_Stack/StackUtil.java new file mode 100644 index 0000000000..782c7d59a6 --- /dev/null +++ b/group11/1310368322/src/data_structure/baseDataStructure_5_Stack/StackUtil.java @@ -0,0 +1,106 @@ +package DataStructure_5_Stack; + +import java.util.Stack; + +public class StackUtil { + /* + * ����ջ�е�Ԫ����Integer����ջ����ջ���ǣ� 5,4,3,2,1 ���ø÷����󣬴�ջ����ջ�׻��� 1,2,3,4,5 + * ע�⣺ ֻ��ʹ�� Stack�Ļ�����������push,pop,peek,isEmpty + */ + public static void reverse(Stack s){ + if(s.isEmpty()){ return; } + int length = s.size(); + Object []temp = new Object[length]; + for(int i = 0; i < length; i++){ + temp[i] = s.pop(); + } + for(int i = 0; i < length; i++){ + s.push(temp[i]); + } + return; + } + + /* + * ɾ��ջ��ָ��Ԫ�أ�ע�⣺ֻ��ʹ��Stack�Ļ�����������push,pop,peek,isEmpty + * + */ + public static void remove(Stack s, Object o){ + int length = s.size(); + Object elementTemp; + System.out.println(length); + int count = 0; + Object []temp = new Object[length]; + if(s.isEmpty()){ return; } + for(int i = 0; i < length;i++){ + elementTemp = s.pop(); + if(!o.equals(elementTemp)){ + temp[count++] = elementTemp; + System.out.println(temp[i]); + } + } + + for(int i = count-1; i >= 0; i--){ + s.push(temp[i]); + } + return; + } + + /* + * ��ջ��ȡ��len��Ԫ�أ�ԭ��ջ�е�Ԫ�ر��ֲ��� + * @param len + * @return + */ + public static Object[] getTop(Stack s , int len){ + if(s.isEmpty() || len > s.size() || len < 0){ + return null; + } + Object []result = new Object[len]; + for(int i = 0; i < len; i++){ + result[i] = s.pop(); + } + return result; + } + + /* + * �ַ��� s ���ܰ�����Щ�ַ��� () [] {}, a, b, c ... x, y, z + * ʹ�ö�ջ����ַ��� s �е������Dz��dzɶԳ��ֵ� + * ���磺 s = ��([e{d}f])��,����ַ����е������dzɶԳ��ֵģ��÷������� true + * ����� s = "([b{x]})",����ַ����е����Ų��dzɶԳ��ֵģ��÷��� ���� false + * @param s + * @return + */ + public static boolean isValidPairs(String s){ + Stack stack = new Stack(); + System.out.println(stack.isEmpty()); + char elementTemp; + boolean tag = false; + char [] a = s.toCharArray(); + for(int i = 0; i < a.length; i++){ + if((!tag) && (a[i] == '(' || a[i] == ')' || a[i] == '[' || a[i] == ']' || a[i] == '{' || a[i] == '}')){ + stack.push(a[i]); + tag = true; + }else{ + if(a[i] == '(' || a[i] == ')' || a[i] == '[' || a[i] == ']' || a[i] == '{' || a[i] == '}'){ + elementTemp = (char) stack.pop(); + switch(elementTemp){ + case '(': if(a[i]==')'){}else{ stack.push(elementTemp); stack.push(a[i]); }; break; + case '[': if(a[i]==']'){}else{ stack.push(elementTemp); stack.push(a[i]); }; break; + case '{': if(a[i]=='}'){}else{ stack.push(elementTemp); stack.push(a[i]); }; break; + + } + } + } + + } + if(stack.isEmpty()){ + return true; + } + return false; + } +} + + + + + + diff --git a/group11/1310368322/src/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java b/group11/1310368322/src/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java new file mode 100644 index 0000000000..c7285dd9a2 --- /dev/null +++ b/group11/1310368322/src/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java @@ -0,0 +1,106 @@ +package dataStructure_6InfixExpr; + +import java.util.Stack; + +public class InfixExpr { + + String expr = null; + + public InfixExpr(String expr){ + this.expr = expr; + } + + public double evaluate(){ + + Stack operatorStack = new Stack(); + Stack operandStack = new Stack(); + + int tag = -1; + for(int i = 0; i < expr.length(); i++){ + if(operatorStack.isEmpty()){ + tag = -1; + } + char c = expr.charAt(i); + if( tag == 1 && (c == '+' || c == '-' || c == '*' || c == '/')){ + System.out.println("i= " + i); + char down = (char) operatorStack.pop(); + System.out.println("down: " + down); + System.out.println("up: " + c); + if(judgePriority(down,c)){ + double operand = (double) operandStack.pop(); + double operanded = (double) operandStack.pop(); + operandStack.push(operator(down,operanded,operand)); + operatorStack.push(c); + }else{ + operatorStack.push(down); + operatorStack.push(c); + } + }else if(tag == -1 && (c == '+' || c == '-' || c == '*' || c == '/')){ + tag = 1; + operatorStack.push(c); + + }else{ + String number = extractNumber(i,expr); + int length = number.length(); + i += length-1; + double operand = Double.parseDouble(number); + operandStack.push(operand); + } + } + + while(!operatorStack.isEmpty()){ + char operator = (char) operatorStack.pop(); + System.out.println(operator); + double operand = (double) operandStack.pop(); + System.out.println(operand); + double operanded = (double) operandStack.pop(); + System.out.println(operanded); + operandStack.push( operator(operator,operanded,operand)); + } + + return (double) operandStack.pop(); + } + + private String extractNumber(int i, String expr2) { + + StringBuffer buffer = new StringBuffer(); + while( (expr.charAt(i) != '+') && (expr.charAt(i) != '-') && (expr.charAt(i) != '*') && (expr.charAt(i) != '/') ){ + buffer.append(expr.charAt(i)); + if(i >= expr2.length()-1){ + break; + } + i++; + } + return buffer.toString(); + } + + private boolean judgePriority(char down, char up) { + boolean tag = false; + + if((up == '+' || up == '-') && (down == '*' || down == '/')){ + tag = true; + }else if( (up == '*') && (down == '/')){ + tag = true; + }else if( (up == '/') && (down == '*')){ + tag = true; + }else if( (up == '+') && (down == '-') ){ + tag = true; + }else if( (up == '-') && (down == '+') ){ + tag = true; + } + return tag; + } + + private double operator(char operator, double operanded, double operand) { + double result = 0; + + switch(operator){ + case '+': result = operanded + operand; break; + case '-': result = operanded - operand; break; + case '*': System.out.println("�˷�"); result = operanded * operand; break; + case '/': result = operanded / operand; break; + } + + return result; + } +} diff --git a/group11/1310368322/test/Mini_JVM/EmployeeV1.java b/group11/1310368322/test/Mini_JVM/EmployeeV1.java new file mode 100644 index 0000000000..acbc34c9bb --- /dev/null +++ b/group11/1310368322/test/Mini_JVM/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.coderising.jvm.loader; + +public class EmployeeV1 { + private String name; + private int age; + + public EmployeeV1(String name, int age){ + this.name = name; + this.age = age; + } + + public void setName(String name){ + this.name = name; + } + + public void setAge(int age){ + this.age = age; + } + + public void sayHello(){ + System.out.println("Hello, this is class Employee"); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + } +} diff --git a/group11/1310368322/test/Mini_JVM/TestClassFileLoader.java b/group11/1310368322/test/Mini_JVM/TestClassFileLoader.java new file mode 100644 index 0000000000..d1874a0834 --- /dev/null +++ b/group11/1310368322/test/Mini_JVM/TestClassFileLoader.java @@ -0,0 +1,246 @@ +package com.coderising.jvm.loader; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.List; + +import org.junit.*; + +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.*; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; + +public class TestClassFileLoader { + static String path1 = "D:/ProgramWorld"; + static String path2 = "D:/ProgramWorld/Java"; + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/loader/EmployeeV1"; + static String classPath1 = "D:/ProgramWorld/Java/Practice/LangSi/2017������Ⱥ/bin/com/coderising/jvm/loader/EmployeeV1.class"; + static String classPath2 = "D:/TestClass.class"; + static ClassFile clzFile = null; + + + @Test + public void test() { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + String clzPath = loader.getClassPath(); + Assert.assertEquals(path1 + ";" + path2, clzPath); + } + @Test + public void testClassFileLength() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "D:/ProgramWorld/Java/Practice/LangSi/2017������Ⱥ/bin/com/coderising/jvm/loader/EmployeeV1.class"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // ע�⣺ ����ֽ������ܺ����JVM�汾�й�ϵ������Կ�������õ��ൽ���ж�� + Assert.assertEquals(1058,byteCodes.length); + } + @Test + public void testMagicNumber() throws IOException{ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "D:/ProgramWorld/Java/Practice/LangSi/2017������Ⱥ/bin/com/coderising/jvm/loader/EmployeeV1.class"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{ + byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3] + }; + System.out.println("ddd"); + String actualValue = this.byteToHexString(codes); + Assert.assertEquals("cafebabe",actualValue); + + } + + private String byteToHexString(byte[] codes){ + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < codes.length; i++){ + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if(strHex.length() < 2){ + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + + //--------------------------------------------- + + + @Test + public void testVersion() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + clzFile = loader.loadClass(classPath2); + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(51, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool() throws IOException{ + + ClassFileLoader loader = new ClassFileLoader(); + clzFile = loader.loadClass(classPath1); + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //��鼸���� + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex() throws IOException{ + + ClassFileLoader loader = new ClassFileLoader(); + clzFile = loader.loadClass(classPath1); + ClassIndex clzIndex = clzFile.getClzIndex(); + System.out.println("clzIndex="+clzIndex); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + System.out.println(thisClassInfo.getClassName()); + System.out.println(superClassInfo.getClassName()); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + + // --------------------- ������ JVM + @Test + public void testReadFields() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + clzFile = loader.loadClass(classPath1); + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + + @Test + public void testMethods() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + clzFile = loader.loadClass(classPath1); + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } + + +} diff --git a/group11/1310368322/test/FileDownloaderTest.java b/group11/1310368322/test/data_structure/BigHomework/Download/FileDownloaderTest.java similarity index 100% rename from group11/1310368322/test/FileDownloaderTest.java rename to group11/1310368322/test/data_structure/BigHomework/Download/FileDownloaderTest.java diff --git a/group11/1310368322/test/ArrayUtilTest.java b/group11/1310368322/test/data_structure/baseDataStructure_2/ArrayUtilTest.java similarity index 100% rename from group11/1310368322/test/ArrayUtilTest.java rename to group11/1310368322/test/data_structure/baseDataStructure_2/ArrayUtilTest.java diff --git a/group11/1310368322/test/data_structure/baseDataStructure_3/TestLinkedList.java b/group11/1310368322/test/data_structure/baseDataStructure_3/TestLinkedList.java new file mode 100644 index 0000000000..343f9d6f39 --- /dev/null +++ b/group11/1310368322/test/data_structure/baseDataStructure_3/TestLinkedList.java @@ -0,0 +1,25 @@ +package DataStructure_3; + +import static org.junit.Assert.*; +import org.junit.Assert; +import org.junit.Test; + +public class TestLinkedList { + + @Test + public void test() { + LinkedList L = new LinkedList(); + Assert.assertEquals("[]", L.toString()); + + L.add(1); + L.reverse(); + Assert.assertEquals("[1]", L.toString()); + + L.add(2); + L.add(3); + L.add(4); + L.reverse(); + Assert.assertEquals("[4,3,2,1]",L.toString()); + } + +} diff --git a/group11/1310368322/test/data_structure/baseDataStructure_4_LRU/TestLRUPageFrame.java b/group11/1310368322/test/data_structure/baseDataStructure_4_LRU/TestLRUPageFrame.java new file mode 100644 index 0000000000..227599c187 --- /dev/null +++ b/group11/1310368322/test/data_structure/baseDataStructure_4_LRU/TestLRUPageFrame.java @@ -0,0 +1,31 @@ +package DataStructure_4_LRU; + +import static org.junit.Assert.*; +import org.junit.*; + +import org.junit.Test; + +public class TestLRUPageFrame { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3);// ����ҳ��洢����Ϊ3������ҳ�� + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7",frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0",frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1",frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2",frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2",frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3",frame.toString()); + } + +} diff --git a/group11/1310368322/test/data_structure/baseDataStructure_5_Stack/TestStackUtil.java b/group11/1310368322/test/data_structure/baseDataStructure_5_Stack/TestStackUtil.java new file mode 100644 index 0000000000..0b227e9ff6 --- /dev/null +++ b/group11/1310368322/test/data_structure/baseDataStructure_5_Stack/TestStackUtil.java @@ -0,0 +1,77 @@ +package DataStructure_5_Stack; + +import java.util.Stack; + +import org.junit.Assert; + +import org.junit.Test; + +public class TestStackUtil { + + @Test + public void test_reverse_1() { + Stack s = new Stack(); + for(int i = 0; i < 5; i++){ + s.push(i+1); + } + System.out.println(s.toString()); + StackUtil.reverse(s); + System.out.println(s.toString()); + } + + @Test + public void test_reverse_2() { + Stack s = new Stack(); + System.out.println(s.isEmpty()); + System.out.println(s.toString()); + StackUtil.reverse(s); + System.out.println(s.toString()); + } + + @Test + public void testRemove_1(){ + Stack actual = new Stack(); + Stack expected = new Stack(); + for(int i = 0; i < 5; i++){ + actual.push(i+1); + if(i != 2){ expected.push(i+1); } + } + StackUtil.remove(actual, 3); + Assert.assertEquals(expected, actual); + } + @Test + public void testRemove_2(){ + Stack actual = new Stack(); + Stack expected = new Stack(); + StackUtil.remove(actual, 3); + Assert.assertEquals(expected, actual); + } + + @Test + public void testGetTop(){ + Stack s = new Stack(); + for(int i = 0; i < 5; i++){ + s.push(i+1); + } + Object expected[] = {5,4,3}; + Object[] actual = StackUtil.getTop(s, 3); + Assert.assertArrayEquals(expected, actual); + + } + + + @Test + public void testIsValidPairs_1(){ + boolean actual = StackUtil.isValidPairs("([e{d}f])"); + boolean expected = true; + Assert.assertEquals(expected, actual); + } + + @Test + public void testValidPairs_2(){ + boolean actual = StackUtil.isValidPairs("([b{x]})"); + boolean expected = false; + Assert.assertEquals(expected, actual); + } + +} diff --git a/group11/1310368322/test/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java b/group11/1310368322/test/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java new file mode 100644 index 0000000000..c7285dd9a2 --- /dev/null +++ b/group11/1310368322/test/data_structure/baseDataStructure_6InfixExpr/InfixExpr.java @@ -0,0 +1,106 @@ +package dataStructure_6InfixExpr; + +import java.util.Stack; + +public class InfixExpr { + + String expr = null; + + public InfixExpr(String expr){ + this.expr = expr; + } + + public double evaluate(){ + + Stack operatorStack = new Stack(); + Stack operandStack = new Stack(); + + int tag = -1; + for(int i = 0; i < expr.length(); i++){ + if(operatorStack.isEmpty()){ + tag = -1; + } + char c = expr.charAt(i); + if( tag == 1 && (c == '+' || c == '-' || c == '*' || c == '/')){ + System.out.println("i= " + i); + char down = (char) operatorStack.pop(); + System.out.println("down: " + down); + System.out.println("up: " + c); + if(judgePriority(down,c)){ + double operand = (double) operandStack.pop(); + double operanded = (double) operandStack.pop(); + operandStack.push(operator(down,operanded,operand)); + operatorStack.push(c); + }else{ + operatorStack.push(down); + operatorStack.push(c); + } + }else if(tag == -1 && (c == '+' || c == '-' || c == '*' || c == '/')){ + tag = 1; + operatorStack.push(c); + + }else{ + String number = extractNumber(i,expr); + int length = number.length(); + i += length-1; + double operand = Double.parseDouble(number); + operandStack.push(operand); + } + } + + while(!operatorStack.isEmpty()){ + char operator = (char) operatorStack.pop(); + System.out.println(operator); + double operand = (double) operandStack.pop(); + System.out.println(operand); + double operanded = (double) operandStack.pop(); + System.out.println(operanded); + operandStack.push( operator(operator,operanded,operand)); + } + + return (double) operandStack.pop(); + } + + private String extractNumber(int i, String expr2) { + + StringBuffer buffer = new StringBuffer(); + while( (expr.charAt(i) != '+') && (expr.charAt(i) != '-') && (expr.charAt(i) != '*') && (expr.charAt(i) != '/') ){ + buffer.append(expr.charAt(i)); + if(i >= expr2.length()-1){ + break; + } + i++; + } + return buffer.toString(); + } + + private boolean judgePriority(char down, char up) { + boolean tag = false; + + if((up == '+' || up == '-') && (down == '*' || down == '/')){ + tag = true; + }else if( (up == '*') && (down == '/')){ + tag = true; + }else if( (up == '/') && (down == '*')){ + tag = true; + }else if( (up == '+') && (down == '-') ){ + tag = true; + }else if( (up == '-') && (down == '+') ){ + tag = true; + } + return tag; + } + + private double operator(char operator, double operanded, double operand) { + double result = 0; + + switch(operator){ + case '+': result = operanded + operand; break; + case '-': result = operanded - operand; break; + case '*': System.out.println("�˷�"); result = operanded * operand; break; + case '/': result = operanded / operand; break; + } + + return result; + } +} diff --git a/group11/252308879/README.md b/group11/252308879/README.md new file mode 100644 index 0000000000..99f5dc58e0 --- /dev/null +++ b/group11/252308879/README.md @@ -0,0 +1,29 @@ +Coding2017 项目 +=== + +## 简介 + +* 考虑到目前的项目目录比较凌乱,所以整理一下目录。目前还未整理完成。 + +* 该项目主要是个人的日常作业,包含三大部分(后续会更多): + * 前三周的打基础(计算机系统知识) + * 数据结构 + * mini-jvm + +--- + +## 目录 + +[TOC] + +--- + +## 正文 + +* data-structure 项目中主要包含前三周的作业 + * 基本的数据结构 + * 解析struts.xml + * 多线程下载 +* mini-jvm 项目中主要包含解析jvm的作业 + +* 在目前这两个大模块中,都包含了每周的数据结构练习 diff --git a/group11/252308879/data-structure/pom.xml b/group11/252308879/data-structure/pom.xml new file mode 100644 index 0000000000..42eb53c993 --- /dev/null +++ b/group11/252308879/data-structure/pom.xml @@ -0,0 +1,68 @@ + + 4.0.0 + + + com.pan + 252308879 + 1.0.0-SNAPSHOT + + + data-structure + 1.0.0-SNAPSHOT + jar + + data-structure + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + + + dom4j + dom4j + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + + + + + org.apache.maven.plugins + maven-source-plugin + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + diff --git a/group11/252308879/data-structure/src/main/java/com/pan/basic/BinaryTreeNode.java b/group11/252308879/data-structure/src/main/java/com/pan/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..aab398a9b6 --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/basic/BinaryTreeNode.java @@ -0,0 +1,32 @@ +package com.pan.basic; + +public class BinaryTreeNode { + + private Object data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public Object getData() { + return data; + } + public void setData(Object data) { + this.data = data; + } + public BinaryTreeNode getLeft() { + return left; + } + public void setLeft(BinaryTreeNode left) { + this.left = left; + } + public BinaryTreeNode getRight() { + return right; + } + public void setRight(BinaryTreeNode right) { + this.right = right; + } + + public BinaryTreeNode insert(Object o){ + return null; + } + +} diff --git a/group11/252308879/data-structure/src/main/java/com/pan/basic/Iterator.java b/group11/252308879/data-structure/src/main/java/com/pan/basic/Iterator.java new file mode 100644 index 0000000000..70735fa34e --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/basic/Iterator.java @@ -0,0 +1,7 @@ +package com.pan.basic; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group11/252308879/data-structure/src/main/java/com/pan/basic/List.java b/group11/252308879/data-structure/src/main/java/com/pan/basic/List.java new file mode 100644 index 0000000000..8ac9cf8e2e --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/basic/List.java @@ -0,0 +1,9 @@ +package com.pan.basic; + +public interface List { + public void add(Object o); + public void add(int index, Object o); + public Object get(int index); + public Object remove(int index); + public int size(); +} diff --git a/group11/252308879/data-structure/src/main/java/com/pan/basic/Queue.java b/group11/252308879/data-structure/src/main/java/com/pan/basic/Queue.java new file mode 100644 index 0000000000..874d8a5690 --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/basic/Queue.java @@ -0,0 +1,19 @@ +package com.pan.basic; + +public class Queue { + + public void enQueue(Object o){ + } + + public Object deQueue(){ + return null; + } + + public boolean isEmpty(){ + return false; + } + + public int size(){ + return -1; + } +} diff --git a/group11/252308879/data-structure/src/main/java/com/pan/linklist/LRUPageFrame.java b/group11/252308879/data-structure/src/main/java/com/pan/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..5208e5bc76 --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/linklist/LRUPageFrame.java @@ -0,0 +1,133 @@ +package com.pan.linklist; + + +/* + * 用双向链表实现LRU算法 + */ +public class LRUPageFrame { + private static class Node{ + Node prev; + Node next; + int pageNum = -1;// 物理页 + + Node(){ + + } + } + + private int capacity; + + private Node first;// 链表头 + private Node last;// 链表尾 + boolean tag = false; + + public LRUPageFrame(int capacity){ + this.capacity = capacity; + + for(int i = 0; i < capacity; i++){ + Node curNode = new Node(); + if(null == first){ + last = first = curNode; + }else{ + last.next = curNode; + curNode.prev = last; + last = last.next; + } + last.next = null; + } + } + public void printList(){ + Node curNode = first; + while(curNode != null){ + curNode = curNode.next; + } + } + /* + * 获取缓存中对象 + * @param key + * @return + */ + public void access(int pageNum){ + printList(); + Node index = findLogicPage(pageNum); + modifyPhysicalPage(index,pageNum); + } + + /* + * @param pageNum 表示要查询的逻辑页面 + * @return 若在物理页中找到要查询的逻辑页面,则返回该物理页节点的引用,否则返回null + */ + public Node findLogicPage(int pageNum){ + + Node index = null; + Node curNode = first; + while(curNode != null){ + if(curNode.pageNum == pageNum){ + index = curNode; + tag = true; + } + curNode = curNode.next; + } + return index; + } + /* + * @prama index 代表了 有逻辑页的物理页的节点的引用 + */ + public void modifyPhysicalPage(Node index,int pageNum){ + push(pageNum,index); + } + /* + * @param pageNum 要 push的逻辑页面, 默认栈顶是 first, bottom 栈底 指定了栈的大小 + */ + public void push(int pageNum,Node bottom){ + Node index = checkWhichListNodeNotUsed(); + if(index != null){ + index.pageNum = pageNum; + return; + } + + Node lastNode; + if(null == bottom){ + lastNode = last; + }else{ + lastNode = bottom; + } + Node curNode = lastNode.prev; + while(curNode != null){ + lastNode.pageNum = curNode.pageNum; + lastNode = curNode; + curNode = curNode.prev; + } + lastNode.pageNum = pageNum; + return; + } + + /* + * @return 返回物理页中 pageNum 没有被使用的节点的引用(返回栈中最下面的),如果全部都被使用,则返回 null + */ + public Node checkWhichListNodeNotUsed(){ + Node node = first; + Node index = null; + while(node != null){ + if(node.pageNum == -1){ + index = node; + } + node = node.next; + } + return index; + } + + public String toString(){ + StringBuffer buffer = new StringBuffer(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } +} diff --git a/group11/252308879/data-structure/src/main/java/com/pan/stack/StackUtil.java b/group11/252308879/data-structure/src/main/java/com/pan/stack/StackUtil.java new file mode 100644 index 0000000000..74918b1e37 --- /dev/null +++ b/group11/252308879/data-structure/src/main/java/com/pan/stack/StackUtil.java @@ -0,0 +1,141 @@ +package com.pan.stack; + + +import java.util.Stack; + +/** + * Created by QiPan on 2017/4/12. + */ +public class StackUtil { + + public static void bad_reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack<>(); + while(!s.isEmpty()){ + tmpStack.push(s.pop()); + } + + s = tmpStack; + + } + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Integer top = s.pop(); + reverse(s); + addToBottom(s,top); + + + } + public static void addToBottom(Stack s, Integer value){ + if(s.isEmpty()){ + s.push(value); + } else{ + Integer top = s.pop(); + addToBottom(s,value); + s.push(top); + } + + } + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack(); + + while(!s.isEmpty()){ + Object value = s.pop(); + if(!value.equals(o)){ + tmpStack.push(value); + } + } + + while(!tmpStack.isEmpty()){ + s.push(tmpStack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + + if(s == null || s.isEmpty() || s.size() stack = new Stack<>(); + for(int i=0;i + 4.0.0 + + + com.pan + 252308879 + 1.0.0-SNAPSHOT + + + mini-jvm + 1.0.0-SNAPSHOT + jar + + mini-jvm + http://maven.apache.org + + + UTF-8 + + + + + com.pan + data-structure + 1.0.0-SNAPSHOT + + + + junit + junit + + + org.apache.commons + commons-lang3 + + + commons-io + commons-io + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + + + + + org.apache.maven.plugins + maven-source-plugin + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/alg/LRUPageFrame.java b/group11/252308879/mini-jvm/src/main/java/com/pan/alg/LRUPageFrame.java new file mode 100644 index 0000000000..d9455d3807 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/alg/LRUPageFrame.java @@ -0,0 +1,133 @@ +package com.pan.alg; + + +/* + * 用双向链表实现LRU算法 + */ +public class LRUPageFrame { + private static class Node{ + Node prev; + Node next; + int pageNum = -1;// 物理页 + + Node(){ + + } + } + + private int capacity; + + private Node first;// 链表头 + private Node last;// 链表尾 + boolean tag = false; + + public LRUPageFrame(int capacity){ + this.capacity = capacity; + + for(int i = 0; i < capacity; i++){ + Node curNode = new Node(); + if(null == first){ + last = first = curNode; + }else{ + last.next = curNode; + curNode.prev = last; + last = last.next; + } + last.next = null; + } + } + public void printList(){ + Node curNode = first; + while(curNode != null){ + curNode = curNode.next; + } + } + /* + * 获取缓存中对象 + * @param key + * @return + */ + public void access(int pageNum){ + printList(); + Node index = findLogicPage(pageNum); + modifyPhysicalPage(index,pageNum); + } + + /* + * @param pageNum 表示要查询的逻辑页面 + * @return 若在物理页中找到要查询的逻辑页面,则返回该物理页节点的引用,否则返回null + */ + public Node findLogicPage(int pageNum){ + + Node index = null; + Node curNode = first; + while(curNode != null){ + if(curNode.pageNum == pageNum){ + index = curNode; + tag = true; + } + curNode = curNode.next; + } + return index; + } + /* + * @prama index 代表了 有逻辑页的物理页的节点的引用 + */ + public void modifyPhysicalPage(Node index,int pageNum){ + push(pageNum,index); + } + /* + * @param pageNum 要 push的逻辑页面, 默认栈顶是 first, bottom 栈底 指定了栈的大小 + */ + public void push(int pageNum,Node bottom){ + Node index = checkWhichListNodeNotUsed(); + if(index != null){ + index.pageNum = pageNum; + return; + } + + Node lastNode; + if(null == bottom){ + lastNode = last; + }else{ + lastNode = bottom; + } + Node curNode = lastNode.prev; + while(curNode != null){ + lastNode.pageNum = curNode.pageNum; + lastNode = curNode; + curNode = curNode.prev; + } + lastNode.pageNum = pageNum; + return; + } + + /* + * @return 返回物理页中 pageNum 没有被使用的节点的引用(返回栈中最下面的),如果全部都被使用,则返回 null + */ + public Node checkWhichListNodeNotUsed(){ + Node node = first; + Node index = null; + while(node != null){ + if(node.pageNum == -1){ + index = node; + } + node = node.next; + } + return index; + } + + public String toString(){ + StringBuffer buffer = new StringBuffer(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/alg/StackUtil.java b/group11/252308879/mini-jvm/src/main/java/com/pan/alg/StackUtil.java new file mode 100644 index 0000000000..01a7f2da52 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/alg/StackUtil.java @@ -0,0 +1,141 @@ +package com.pan.alg; + + +import java.util.Stack; + +/** + * Created by QiPan on 2017/4/12. + */ +public class StackUtil { + + public static void bad_reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack<>(); + while(!s.isEmpty()){ + tmpStack.push(s.pop()); + } + + s = tmpStack; + + } + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Integer top = s.pop(); + reverse(s); + addToBottom(s,top); + + + } + public static void addToBottom(Stack s, Integer value){ + if(s.isEmpty()){ + s.push(value); + } else{ + Integer top = s.pop(); + addToBottom(s,value); + s.push(top); + } + + } + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack(); + + while(!s.isEmpty()){ + Object value = s.pop(); + if(!value.equals(o)){ + tmpStack.push(value); + } + } + + while(!tmpStack.isEmpty()){ + s.push(tmpStack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + + if(s == null || s.isEmpty() || s.size() stack = new Stack<>(); + for(int i=0;i clzPaths = new ArrayList(); + int countForClassPath = 0; + int countForReadBinaryCode = 0; + byte [] a = new byte[10000]; + + /* 从指定路径读取二进制文件流,并将其保存到一个字节数组中,并返回 + * @Parameters 指定路径 + * @字节数组 + */ + public byte[] readBinaryCode(String className) throws IOException{ + DataInputStream dis = new DataInputStream( + new BufferedInputStream(new FileInputStream(className))); + for(int i = 0; dis.available() != 0; i++){ + a[i] = dis.readByte(); + countForReadBinaryCode++; + } + byte []target = new byte[countForReadBinaryCode]; + System.arraycopy(a, 0, target, 0, countForReadBinaryCode); + dis.close(); + return target; + } + + public void addClassPath(String path){ + clzPaths.add(path); + countForClassPath++; + } + + public String getClassPath(){ + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < countForClassPath; i++ ){ + if(i==countForClassPath-1){ + buffer.append(clzPaths.get(i)); + }else{ + buffer.append(clzPaths.get(i)+";"); + } + } + return buffer.toString(); + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/EmployeeV1.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/EmployeeV1.java new file mode 100644 index 0000000000..71f9ff54a4 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/EmployeeV1.java @@ -0,0 +1,30 @@ +package com.pan.jvm; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/AttributeInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..1a81e8b473 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/AttributeInfo.java @@ -0,0 +1,19 @@ +package com.pan.jvm.attr; + +public abstract class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + int attrNameIndex; + int attrLen ; + public AttributeInfo(int attrNameIndex, int attrLen) { + + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/CodeAttr.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..80a05a9ac0 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/CodeAttr.java @@ -0,0 +1,94 @@ +package com.pan.jvm.attr; + +import com.pan.jvm.clz.ClassFile; +import com.pan.jvm.loader.ByteCodeIterator; + + +public class CodeAttr extends AttributeInfo { + private int maxStack ; + private int maxLocals ; + private int codeLen ; + private String code; + public String getCode() { + return code; + } + + //private ByteCodeCommand[] cmds ; + //public ByteCodeCommand[] getCmds() { + // return cmds; + //} + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + //this.cmds = cmds; + } + + public void setLineNumberTable(LineNumberTable t) { + this.lineNumTable = t; + } + + public void setLocalVariableTable(LocalVariableTable t) { + this.localVarTable = t; + } + + public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2ToInt(); + int attrLen = iter.nextU4ToInt(); + int maxStack = iter.nextU2ToInt(); + int maxLocals = iter.nextU2ToInt(); + int codeLen = iter.nextU4ToInt(); + + String code = iter.nextUxToHexString(codeLen); + + System.out.println("CODE-code: "+code); + + CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, maxLocals, codeLen, code); + + int exceptionTableLen = iter.nextU2ToInt(); + + if (exceptionTableLen > 0){ + String exTable = iter.nextUxToHexString(exceptionTableLen); + System.out.println("Encountered exception table, just ignore!"); + } + + // 处理子属性 + int subAttrCount = iter.nextU2ToInt(); + for (int i = 1; i <= subAttrCount; i++) { + int suAttrIndex = iter.nextU2ToInt(); + String subAttrName = clzFile.getConstantPool().getUTF8String(suAttrIndex); + + iter.back(2);// 便于在子属性中获取 attrNameIndex + + if (AttributeInfo.LINE_NUM_TABLE.equalsIgnoreCase(subAttrName)){ + LineNumberTable lineNumberTable = LineNumberTable.parse(iter); + codeAttr.setLineNumberTable(lineNumberTable); + }else if (AttributeInfo.LOCAL_VAR_TABLE.equalsIgnoreCase(subAttrName)){ + LocalVariableTable localVariableTable = LocalVariableTable.parse(iter); + codeAttr.setLocalVariableTable(localVariableTable); + }else if (AttributeInfo.STACK_MAP_TABLE.equalsIgnoreCase(subAttrName)){ + StackMapTable stackMapTable = StackMapTable.parse(iter); + codeAttr.setStackMapTable(stackMapTable); + }else { + throw new RuntimeException("Need code to process :" + subAttrName); + } + + } + return codeAttr; + } + private void setStackMapTable(StackMapTable t) { + this.stackMapTable = t; + + } + + + + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LineNumberTable.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..563e8b19d5 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LineNumberTable.java @@ -0,0 +1,53 @@ +package com.pan.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +import com.pan.jvm.loader.ByteCodeIterator; + +public class LineNumberTable extends AttributeInfo { + List items = new ArrayList(); + + private static class LineNumberItem{ + int startPC; + int lineNum; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + public void addLineNumberItem(LineNumberItem item){ + this.items.add(item); + } + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + + } + + public static LineNumberTable parse(ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2ToInt(); + int attrLen = iter.nextU4ToInt(); + LineNumberTable lineNumberTable = new LineNumberTable(attrNameIndex, attrLen); + + int attrItemSize = iter.nextU2ToInt(); + for (int i = 1; i <= attrItemSize; i++) { + LineNumberItem lineNumberItem = new LineNumberItem(); + lineNumberItem.setStartPC(iter.nextU2ToInt()); + lineNumberItem.setLineNum(iter.nextU2ToInt()); + + lineNumberTable.addLineNumberItem(lineNumberItem); + } + return lineNumberTable; + } + + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableItem.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..7e202a3931 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableItem.java @@ -0,0 +1,39 @@ +package com.pan.jvm.attr; + +public class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getNameIndex() { + return nameIndex; + } + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + public int getDescIndex() { + return descIndex; + } + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableTable.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..74c73baac6 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/LocalVariableTable.java @@ -0,0 +1,42 @@ +package com.pan.jvm.attr; + + +import java.util.ArrayList; +import java.util.List; + +import com.pan.jvm.loader.ByteCodeIterator; + +public class LocalVariableTable extends AttributeInfo{ + + List items = new ArrayList(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LocalVariableTable parse(ByteCodeIterator iter){ + + int attrNameIndex = iter.nextU2ToInt(); + int attrLen = iter.nextU4ToInt(); + + LocalVariableTable localVariableTable = new LocalVariableTable(attrNameIndex, attrLen); + + int attrItemSize = iter.nextU2ToInt(); + for (int i = 1; i <= attrItemSize; i++) { + LocalVariableItem localVariableItem = new LocalVariableItem(); + localVariableItem.setStartPC(iter.nextU2ToInt()); + localVariableItem.setLength(iter.nextU2ToInt()); + localVariableItem.setNameIndex(iter.nextU2ToInt()); + localVariableItem.setDescIndex(iter.nextU2ToInt()); + localVariableItem.setIndex(iter.nextU2ToInt()); + localVariableTable.addLocalVariableItem(localVariableItem); + } + + return localVariableTable; + } + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/StackMapTable.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..8d7c32b4bd --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/attr/StackMapTable.java @@ -0,0 +1,30 @@ +package com.pan.jvm.attr; + + +import com.pan.jvm.loader.ByteCodeIterator; + +public class StackMapTable extends AttributeInfo{ + + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.nextU2ToInt(); + int len = iter.nextU4ToInt(); + StackMapTable t = new StackMapTable(index,len); + + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + String code = iter.nextUxToHexString(len); + t.setOriginalCode(code); + + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/AccessFlag.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..045741bd1e --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.pan.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassFile.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..e632888d89 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassFile.java @@ -0,0 +1,88 @@ +package com.pan.jvm.clz; + +import java.util.ArrayList; +import java.util.List; + +import com.pan.jvm.constant.ClassInfo; +import com.pan.jvm.constant.ConstantPool; +import com.pan.jvm.field.Field; +import com.pan.jvm.method.Method; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + private List fields = new ArrayList(); + private List methods = new ArrayList(); + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + public void addField(Field f){ + this.fields.add(f); + } + public List getFields(){ + return this.fields; + } + public void addMethod(Method m){ + this.methods.add(m); + } + public List getMethods() { + return methods; + } + + + public void print(){ + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + System.out.println("Super Class Name:"+ getSuperClassName()); + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassIndex.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..e09d6f0076 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package com.pan.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ClassInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..b842755586 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ClassInfo.java @@ -0,0 +1,28 @@ +package com.pan.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index; + + public ClassInfo(ConstantPool pool) { + super(pool); + } + + public int getUtf8Index() { + return utf8Index; + } + + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info) constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..464e44a79d --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantInfo.java @@ -0,0 +1,31 @@ +package com.pan.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo() { + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantPool.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..c2da2637c5 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/ConstantPool.java @@ -0,0 +1,32 @@ +package com.pan.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool() { + + } + + public void addConstantInfo(ConstantInfo info) { + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantInfos.get(index); + } + + public String getUTF8String(int index) { + return ((UTF8Info) this.constantInfos.get(index)).getValue(); + } + + public Object getSize() { + return this.constantInfos.size() - 1; + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/FieldRefInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..2aaced31d3 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/FieldRefInfo.java @@ -0,0 +1,58 @@ +package com.pan.jvm.constant; + +public class FieldRefInfo extends ConstantInfo { + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() + " : " + typeInfo.getName() + ":" + typeInfo.getTypeInfo() + "]"; + } + + public String getClassName() { + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info) this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/MethodRefInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..a3e6f969b0 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/MethodRefInfo.java @@ -0,0 +1,58 @@ +package com.pan.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + + return getClassName() + " : " + this.getMethodName() + " : " + this.getParamAndReturnType(); + } + + public String getClassName() { + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo) pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo) pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NameAndTypeInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..30be83ef3a --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,49 @@ +package com.pan.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo { + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + + public void setIndex1(int index1) { + this.index1 = index1; + } + + public int getIndex2() { + return index2; + } + + public void setIndex2(int index2) { + this.index2 = index2; + } + + public int getType() { + return type; + } + + + public String getName() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info) pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info) pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString() { + return "(" + getName() + "," + getTypeInfo() + ")"; + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NullConstantInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..cc6989bef7 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/NullConstantInfo.java @@ -0,0 +1,14 @@ +package com.pan.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo() { + + } + + @Override + public int getType() { + return -1; + } + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/StringInfo.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..ad3f397949 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/StringInfo.java @@ -0,0 +1,28 @@ +package com.pan.jvm.constant; + +public class StringInfo extends ConstantInfo { + private int type = ConstantInfo.STRING_INFO; + private int index; + + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + + public String toString() { + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/UTF8Info.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..502adae968 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/constant/UTF8Info.java @@ -0,0 +1,38 @@ +package com.pan.jvm.constant; + +public class UTF8Info extends ConstantInfo { + private int type = ConstantInfo.UTF8_INFO; + private int length; + private String value; + + public UTF8Info(ConstantPool pool) { + super(pool); + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getType() { + return type; + } + + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value + ")]"; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/field/Field.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/field/Field.java new file mode 100644 index 0000000000..22775d0de7 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/field/Field.java @@ -0,0 +1,47 @@ +package com.pan.jvm.field; + + +import com.pan.jvm.constant.ConstantPool; +import com.pan.jvm.constant.UTF8Info; +import com.pan.jvm.loader.ByteCodeIterator; + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + + + private ConstantPool pool; + + public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + @Override + public String toString() { + String name = ((UTF8Info) pool.getConstantInfo(this.nameIndex)).getValue(); + String desc = ((UTF8Info) pool.getConstantInfo(this.descriptorIndex)).getValue(); + + return name + ":" + desc; + } + + public static Field parse(ConstantPool pool, ByteCodeIterator iter){ + + int accessFlags = iter.nextU2ToInt(); + int nameIndex = iter.nextU2ToInt(); + int descriptorIndex = iter.nextU2ToInt(); + int attrCount = iter.nextU2ToInt(); + System.out.println("Field Attributes Count: " + attrCount); + Field field = new Field(accessFlags, nameIndex, descriptorIndex, pool); + if (attrCount > 0){ + throw new RuntimeException("Attributes Count > 0"); + } + return field; + } + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ByteCodeIterator.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..24f00ccc5d --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,52 @@ +package com.pan.jvm.loader; + +import java.util.Arrays; + +import com.pan.jvm.util.Util; + +public class ByteCodeIterator { + byte[] codes; + int pos = 0; + + ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public byte[] getBytes(int len) { + if (pos + len >= codes.length) { + throw new ArrayIndexOutOfBoundsException(); + } + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos += len; + return data; + } + + public int nextU1toInt() { + return Util.byteToInt(new byte[]{codes[pos++]}); + } + + public int nextU2ToInt() { + return Util.byteToInt(new byte[]{codes[pos++], codes[pos++]}); + } + + public int nextU4ToInt() { + return Util.byteToInt(new byte[]{codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextU4ToHexString() { + return Util.byteToHexString((new byte[]{codes[pos++], codes[pos++], codes[pos++], codes[pos++]})); + } + + public String nextUxToHexString(int len) { + byte[] tmp = new byte[len]; + + for (int i = 0; i < len; i++) { + tmp[i] = codes[pos++]; + } + return Util.byteToHexString(tmp).toLowerCase(); + } + + public void back(int n) { + this.pos -= n; + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileLoader.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..fa25990691 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileLoader.java @@ -0,0 +1,104 @@ +package com.pan.jvm.loader; + +import com.pan.jvm.clz.ClassFile; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList<>(); + + public byte[] readBinaryCode(String className) { + className = className.replace('.', File.separatorChar) + ".class"; + for (String path : this.clzPaths) { + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if (codes != null) { + return codes; + } + } + return null; + } + + private byte[] loadClassFile(String clzFileName) { + File f = new File(clzFileName); + try { + return IOUtils.toByteArray(new FileInputStream(f)); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + + public void addClassPath(String path) { + if (this.clzPaths.contains(path)) { + return; + } + this.clzPaths.add(path); + } + + + public String getClassPath() { + return StringUtils.join(this.clzPaths, ";"); + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + + + // ------------------------------backup------------------------ + public String getClassPath_V1() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < this.clzPaths.size(); i++) { + buffer.append(this.clzPaths.get(i)); + if (i < this.clzPaths.size() - 1) { + buffer.append(";"); + } + } + return buffer.toString(); + } + + private byte[] loadClassFile_V1(String clzFileName) { + + BufferedInputStream bis = null; + try { + File f = new File(clzFileName); + bis = new BufferedInputStream(new FileInputStream(f)); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length = -1; + while ((length = bis.read(buffer)) != -1) { + bos.write(buffer, 0, length); + } + byte[] codes = bos.toByteArray(); + return codes; + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (bis != null) { + try { + bis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return null; + } + + +} \ No newline at end of file diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileParser.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..b2bddb85c2 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/loader/ClassFileParser.java @@ -0,0 +1,172 @@ +package com.pan.jvm.loader; + +import com.pan.jvm.clz.AccessFlag; +import com.pan.jvm.clz.ClassFile; +import com.pan.jvm.clz.ClassIndex; +import com.pan.jvm.constant.*; +import com.pan.jvm.field.Field; +import com.pan.jvm.method.Method; + +import java.io.UnsupportedEncodingException; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + + ByteCodeIterator iterator = new ByteCodeIterator(codes); + String magicNumber = iterator.nextU4ToHexString(); + if (!"cafebabe".equals(magicNumber)) {// 验证是否为Java的.class文件 + return null; + } + ClassFile classFile = new ClassFile(); + classFile.setMinorVersion(iterator.nextU2ToInt()); + classFile.setMajorVersion(iterator.nextU2ToInt()); + + ConstantPool constantPool = parseConstantPool(iterator); + classFile.setConstPool(constantPool); + + AccessFlag flag = parseAccessFlag(iterator); + classFile.setAccessFlag(flag); + + // this clz 和 supper clz + ClassIndex clzIndex = parseClassIndex(iterator); + classFile.setClassIndex(clzIndex); + + // interface + parseInterfaces(iterator); + + // field + parseFields(classFile, iterator); + + // method + parseMethods(classFile, iterator); + + return classFile; + } + + private void parseMethods(ClassFile classFile, ByteCodeIterator iterator) { + int methodsCount = iterator.nextU2ToInt(); + System.out.println("Methods Count: " + methodsCount); + + for (int i = 1; i <= methodsCount; i++) { + Method method = Method.parse(classFile, iterator); + classFile.addMethod(method); + } + } + + + private void parseFields(ClassFile clzFile, ByteCodeIterator iterator) { + int fieldsCount = iterator.nextU2ToInt(); + System.out.println("Field count:" + fieldsCount); + for (int i = 1; i <= fieldsCount; i++) {// 从第一个开始,因为不包含本身 + Field field = Field.parse(clzFile.getConstantPool(), iterator); + clzFile.addField(field); + } + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + AccessFlag accessFlag = new AccessFlag(iter.nextU2ToInt()); + return accessFlag; + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + + int thisClassIndex = iter.nextU2ToInt(); + int supperClassIndex = iter.nextU2ToInt(); + + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(thisClassIndex); + classIndex.setSuperClassIndex(supperClassIndex); + return classIndex; + } + + private void parseInterfaces(ByteCodeIterator iter) { + int interfaceCount = iter.nextU2ToInt(); + + System.out.println("interfaceCount:" + interfaceCount); + + // TODO : 如果实现了interface, 这里需要解析 + } + + /** + * 解析常量池 + * + * @param iter + * @return + */ + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + + int constPoolCount = iter.nextU2ToInt(); + + System.out.println("Constant Pool Count :" + constPoolCount); + ConstantPool pool = new ConstantPool(); + // 因为常量池中的信息是从 1 开始的,但是数组或者List 下标是从0开始,所以设置第一个为空的常量 + pool.addConstantInfo(new NullConstantInfo()); + + for (int i = 1; i <= constPoolCount - 1; i++) { + + // 获取标识符信息 + int tag = iter.nextU1toInt(); + + switch (tag) { + + case 7: //CONSTANT_Class + int utf8Index = iter.nextU2ToInt(); + ClassInfo classInfo = new ClassInfo(pool); + classInfo.setUtf8Index(utf8Index); + + pool.addConstantInfo(classInfo); + break; + case 9: // CONSTANT_Fieldref + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + fieldRefInfo.setClassInfoIndex(iter.nextU2ToInt()); + fieldRefInfo.setNameAndTypeIndex(iter.nextU2ToInt()); + + pool.addConstantInfo(fieldRefInfo); + break; + case 10: // CONSTANT_Methodref + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + methodRefInfo.setClassInfoIndex(iter.nextU2ToInt()); + methodRefInfo.setNameAndTypeIndex(iter.nextU2ToInt()); + + pool.addConstantInfo(methodRefInfo); + break; + case 8: + StringInfo info = new StringInfo(pool); + info.setIndex(iter.nextU2ToInt()); + pool.addConstantInfo(info); + break; + case 12: // CONSTANT_NameAndType + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + nameAndTypeInfo.setIndex1(iter.nextU2ToInt()); + nameAndTypeInfo.setIndex2(iter.nextU2ToInt()); + + pool.addConstantInfo(nameAndTypeInfo); + break; + case 1: // CONSTANT_Utf8 + int length = iter.nextU2ToInt(); + byte[] data = iter.getBytes(length); + String value = null; + try { + value = new String(data, "utf-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + UTF8Info utf8Str = new UTF8Info(pool); + utf8Str.setLength(length); + utf8Str.setValue(value); + + pool.addConstantInfo(utf8Str); + break; + default: + throw new RuntimeException("the constant pool tag " + tag + " has not been implemented yet."); + + } + } + System.out.println("Finished reading Constant pool "); + return pool; + } + + +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/method/Method.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/method/Method.java new file mode 100644 index 0000000000..0fbb0f0946 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/method/Method.java @@ -0,0 +1,71 @@ +package com.pan.jvm.method; + + +import com.pan.jvm.attr.AttributeInfo; +import com.pan.jvm.attr.CodeAttr; +import com.pan.jvm.clz.ClassFile; +import com.pan.jvm.loader.ByteCodeIterator; + +public class Method { + + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + + private ClassFile clzFile; + + + public ClassFile getClzFile() { + return clzFile; + } + + public int getNameIndex() { + return nameIndex; + } + public int getDescriptorIndex() { + return descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr code) { + this.codeAttr = code; + } + + public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) { + this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ + int accessFlags = iter.nextU2ToInt(); + int nameIndex = iter.nextU2ToInt(); + int descriptorIndex = iter.nextU2ToInt(); + int attrCount = iter.nextU2ToInt(); + + System.out.println("Method Attributes Count: " + attrCount); + Method method = new Method(clzFile, accessFlags, nameIndex, descriptorIndex); + if (attrCount > 0){ + for (int i = 1; i <= attrCount; i++) { + int attrNameIndex = iter.nextU2ToInt(); + String attrName = clzFile.getConstantPool().getUTF8String(attrNameIndex); + iter.back(2); // 回退两个,便于Code 中读取属性 + if (AttributeInfo.CODE.equalsIgnoreCase(attrName)){ + CodeAttr codeAttr = CodeAttr.parse(clzFile, iter); + method.setCodeAttr(codeAttr); + }else { + throw new RuntimeException("Current Has CODE. Not Support Other"); + } + } + } + return method; + + } +} diff --git a/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/util/Util.java b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/util/Util.java new file mode 100644 index 0000000000..ae130b4183 --- /dev/null +++ b/group11/252308879/mini-jvm/src/main/java/com/pan/jvm/util/Util.java @@ -0,0 +1,23 @@ +package com.pan.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes) { + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + public static String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group11/252308879/mini-jvm/src/test/java/com/pan/alg/LRUPageFrameTest.java b/group11/252308879/mini-jvm/src/test/java/com/pan/alg/LRUPageFrameTest.java new file mode 100644 index 0000000000..8f6803c11f --- /dev/null +++ b/group11/252308879/mini-jvm/src/test/java/com/pan/alg/LRUPageFrameTest.java @@ -0,0 +1,34 @@ +package com.pan.alg; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + frame.access(5); + Assert.assertEquals("5,4,0", frame.toString()); + + } + +} diff --git a/group11/252308879/mini-jvm/src/test/java/com/pan/alg/StackUtilTest.java b/group11/252308879/mini-jvm/src/test/java/com/pan/alg/StackUtilTest.java new file mode 100644 index 0000000000..71671c9b47 --- /dev/null +++ b/group11/252308879/mini-jvm/src/test/java/com/pan/alg/StackUtilTest.java @@ -0,0 +1,76 @@ +package com.pan.alg; + +import java.util.Stack; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +public class StackUtilTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAddToBottom() { + Stack s = new Stack<>(); + s.push(1); + s.push(2); + s.push(3); + + StackUtil.addToBottom(s, 0); + + Assert.assertEquals("[0, 1, 2, 3]", s.toString()); + + } + @Test + public void testReverse() { + Stack s = new Stack<>(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString()); + StackUtil.reverse(s); + Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString()); + } + + @Test + public void testRemove() { + Stack s = new Stack<>(); + s.push(1); + s.push(2); + s.push(3); + StackUtil.remove(s, 2); + Assert.assertEquals("[1, 3]", s.toString()); + } + + @Test + public void testGetTop() { + Stack s = new Stack<>(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + { + Object[] values = StackUtil.getTop(s, 3); + Assert.assertEquals(5, values[0]); + Assert.assertEquals(4, values[1]); + Assert.assertEquals(3, values[2]); + } + } + + @Test + public void testIsValidPairs() { + Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])")); + Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})")); + } + +} diff --git a/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/ClassFileLoaderTest.java b/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/ClassFileLoaderTest.java new file mode 100644 index 0000000000..d341553c70 --- /dev/null +++ b/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/ClassFileLoaderTest.java @@ -0,0 +1,258 @@ +package com.pan.jvm; + +import java.util.List; + +import com.pan.jvm.clz.ClassFile; +import com.pan.jvm.clz.ClassIndex; +import com.pan.jvm.constant.*; +import com.pan.jvm.field.Field; +import com.pan.jvm.loader.ClassFileLoader; +import com.pan.jvm.method.Method; +import com.pan.jvm.util.Util; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + + + + +public class ClassFileLoaderTest { + + + private static final String FULL_QUALIFIED_CLASS_NAME = "com/pan/jvm/EmployeeV1"; + + static String path1 = EmployeeV1.class.getClassLoader().getResource("").getPath() + .replace("test-classes", "classes"); + static String path2 = "C:/temp"; + + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.pan.jvm.EmployeeV1"; + + clzFile = loader.loadClass(className); + clzFile.print(); + } + + + @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.pan.jvm.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1032, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.pan.jvm.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String actualValue = Util.byteToHexString(codes); + + Assert.assertEquals("cafebabe", actualValue); + } + + + /** + * ---------------------------------------------------------------------- + */ + + + @Test + public void testVersion(){ + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + } + + @Test + public void testConstantPool(){ + + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + /** + * 下面是第三次JVM课应实现的测试用例 + */ + @Test + public void testReadFields(){ + + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + @Test + public void testMethods(){ + + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } + + +} diff --git a/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/TestReadCFBB.java b/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/TestReadCFBB.java new file mode 100644 index 0000000000..8590e78c09 --- /dev/null +++ b/group11/252308879/mini-jvm/src/test/java/com/pan/jvm/TestReadCFBB.java @@ -0,0 +1,41 @@ +package com.pan.jvm; + +import com.pan.jvm.loader.ClassFileLoader; +import org.junit.Test; + +import java.io.IOException; + +/** + * 用于测试第一次JVM作业,读取.class作业 和 魔幻数字 + */ +public class TestReadCFBB { + + @Test + public void testClassPath(){ + ClassFileLoader classFileLoader = new ClassFileLoader(); + String path = ClassFileLoader.class.getClassLoader().getResource("").getPath(); + path = path.replace("test-classes", "classes"); + classFileLoader.addClassPath(path); + classFileLoader.addClassPath("d://tmp"); + + String clzPath = classFileLoader.getClassPath(); + System.out.println(clzPath); + } + + + + @Test + public void testReadCFBB() throws IOException { + + ClassFileLoader classFileLoader = new ClassFileLoader(); + String path = ClassFileLoader.class.getClassLoader().getResource("").getPath(); + path = path.replace("test-classes", "classes"); + classFileLoader.addClassPath(path); + byte[] bytes = classFileLoader.readBinaryCode("com.pan.jvm.loader.ClassFileLoader"); + for (byte b : bytes) { + String toHexString = Integer.toHexString(b & 0xFF).toUpperCase(); + System.out.print(toHexString + " "); + } + } + +} diff --git a/group11/252308879/pom.xml b/group11/252308879/pom.xml new file mode 100644 index 0000000000..642387b95a --- /dev/null +++ b/group11/252308879/pom.xml @@ -0,0 +1,140 @@ + + + + + + data-structure + mini-jvm + + + com.pan + 252308879 + pom + 1.0.0-SNAPSHOT + + 4.0.0 + + + UTF-8 + 1.8 + 1.8 + 3.3 + 2.4 + 2.5 + 2.5 + 2.8.2 + 2.3.1 + 2.5 + 2.12.2 + + + + + + junit + junit + 4.12 + test + + + dom4j + dom4j + 1.6.1 + + + org.apache.commons + commons-lang3 + 3.4 + + + commons-io + commons-io + 2.4 + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven_compiler_plugin_version} + + ${java_source_version} + ${java_target_version} + ${project.build.sourceEncoding} + + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + ${maven_surefire_report_plugin} + + false + + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven_source_plugin_version} + + + attach-sources + + jar-no-fork + + + + + true + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven_jar_plugin_version} + + + true + + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven_war_plugin_version} + + + true + + + + + + org.codehaus.mojo + findbugs-maven-plugin + ${findbugs_maven_plugin_version} + + true + target/site + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven_checkstyle_plugin_version} + + + + \ No newline at end of file diff --git a/group11/283091182/mini-jvm-week1-bk/loader/ClassFileLoader.java b/group11/283091182/mini-jvm-week1-bk/loader/ClassFileLoader.java new file mode 100644 index 0000000000..527e2f14d8 --- /dev/null +++ b/group11/283091182/mini-jvm-week1-bk/loader/ClassFileLoader.java @@ -0,0 +1,93 @@ +package com.coderising.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + File classFile = getClassFileFromPath(className); + + byte[] buffer = new byte[1024]; + try { + FileInputStream fis = new FileInputStream(classFile); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + int readLen; + while((readLen = fis.read(buffer))>-1){ + baos.write(buffer, 0, readLen); + } + + return baos.toByteArray(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + + public void addClassPath(String path) { + File clzPath = new File(path); + if(clzPath.exists() && clzPath.isDirectory()){ + this.clzPaths.add(path); + }else{ + System.out.println("Invalid path:"+ path); + } + } + + + + public String getClassPath(){ + StringBuilder sb = new StringBuilder(); + Iterator it = this.clzPaths.iterator(); + while(it.hasNext()){ + if(sb.length()>0){ + sb.append(";"); + } + sb.append(it.next()); + } + return sb.toString(); + } + + public File getClassFileFromPath(String className) { + Iterator it = this.clzPaths.iterator(); + + //replace "." with "\\" in windows + String fullclassPath = className.replaceAll("\\.", (File.separatorChar=='\\')?"\\\\":"/")+".class"; + + while(it.hasNext()){ + File clzFile; + String path = (String)it.next(); + if(path.endsWith(String.valueOf(File.separatorChar))){ + clzFile = new File(path+fullclassPath); + }else{ + clzFile = new File(path+File.separatorChar+fullclassPath); + } + + //Check file before further proceed + if(clzFile.exists()&&clzFile.isFile()){ + return clzFile; + } + } + + throw new RuntimeException("Class not found:"+className); + } + + + +} diff --git a/group11/283091182/mini-jvm-week1-bk/test/ClassFileloaderTest.java b/group11/283091182/mini-jvm-week1-bk/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..21d7e97074 --- /dev/null +++ b/group11/283091182/mini-jvm-week1-bk/test/ClassFileloaderTest.java @@ -0,0 +1,92 @@ +package com.coderising.jvm.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.jvm.loader.ClassFileLoader; + + + + + +public class ClassFileloaderTest { + + + static String path1 = "C:\\Users\\Administrator\\mygit\\coding2017\\liuxin\\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 constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/FieldRefInfo.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..65475e194c --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/MethodRefInfo.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..7f05870020 --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/NameAndTypeInfo.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..402f9dec86 --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/NullConstantInfo.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..936736016f --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/StringInfo.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..f1f8eb4ed4 --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index; + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/constant/UTF8Info.java b/group11/283091182/mini-jvm/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..5cac9f04f7 --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group11/283091182/mini-jvm/com/coderising/jvm/loader/ByteCodeIterator.java b/group11/283091182/mini-jvm/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..514d85e08f --- /dev/null +++ b/group11/283091182/mini-jvm/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,87 @@ +package com.coderising.jvm.loader; + +public class ByteCodeIterator { + private byte[] bytes; + private int pos = 0; + public ByteCodeIterator(byte[] byteCodes){ + this.bytes = byteCodes; + } + + public boolean hasNext(){ + return this.pos < bytes.length-1; + } + + public byte next(){ + byte b = bytes[pos]; + pos ++; + return b; + } + + public byte[] getBytes(int len){ + if(pos+len>bytes.length){ + throw new RuntimeException("Index out of bounds:"+(pos+len)); + } + byte[] bytes = new byte[len]; + int idx = 0; + while(hasNext() && idx", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + + +} diff --git a/group11/283091182/src/com/coderising/array/ArrayList.java b/group11/283091182/src/com/coderising/array/ArrayList.java new file mode 100644 index 0000000000..18b0dcca6f --- /dev/null +++ b/group11/283091182/src/com/coderising/array/ArrayList.java @@ -0,0 +1,116 @@ +package com.coderising.array; + +import java.util.Arrays; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +public class ArrayList implements List { + + private int size = 0; + + private static final int GROW_BY_SIZE = 10; + + private Object[] elementData = new Object[GROW_BY_SIZE]; + + public void add(Object o){ + if(size == elementData.length){ + grow(); + } + elementData[size]=o; + size++; + } + public void add(int index, Object o){ + validate(index); + if(size == elementData.length){ + grow(); + } + for(int i=size;i>index+1;i--){ + elementData[i]=elementData[i-1]; + } + elementData[index]=o; + size++; + } + + public Object get(int index){ + validate(index); + return elementData[index]; + } + + public Object remove(int index){ + validate(index); + Object result = elementData[index]; + for(int i =index;i=size)throw new IndexOutOfBoundsException("Invalid Index:"+pos); + Object result = elementData[pos]; + pos++; + return result; + } + + + } + + private void grow(){ + elementData = Arrays.copyOf(elementData, elementData.length+GROW_BY_SIZE); + } + private void validate(int index){ + if(index<0||index>=size)throw new IndexOutOfBoundsException("Invalid Index:"+index); + } + + @Override + public String toString(){ + StringBuilder sb = new StringBuilder("["); + for(int i=0;i1)sb.append(","); + sb.append(elementData[i]); + } + sb.append("]size=").append(this.size()); + return sb.toString(); + } + + public static void main(String[] args){ + ArrayList l = new ArrayList(); + for(int i=0;i<12;i++){ + l.add(i+""); + } + System.out.println(l); + l.add("aaa"); + System.out.println("After adding aaa:"+l); + l.add(2,"bbb"); + System.out.println("After adding bbb:"+l); + System.out.println(l.get(2)); + System.out.println("After getting:"+l); + System.out.println(l.remove(2)); + System.out.println("After removing:"+l); + Iterator it = l.iterator(); + while(it.hasNext()){ + System.out.println(it.next()); + } + } + +} diff --git a/group11/283091182/src/com/coderising/array/ArrayListTest.java b/group11/283091182/src/com/coderising/array/ArrayListTest.java new file mode 100644 index 0000000000..8bdc0515d1 --- /dev/null +++ b/group11/283091182/src/com/coderising/array/ArrayListTest.java @@ -0,0 +1,142 @@ +/** + * + */ +package com.coderising.array; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * @author Administrator + * + */ +public class ArrayListTest { + + private ArrayList al; + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + System.out.println("SetUp"); + al= new ArrayList(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + System.out.println("TearDown"); + al = null; + } + + /** + * Test method for {@link com.coderising.array.ArrayList#add(java.lang.Object)}. + */ + @Test + public final void testAddObject() { + al.add("aaa"); + al.add("bbb"); + al.add("ccc"); + assertEquals("aaa",al.get(0)); + assertEquals("bbb",al.get(1)); + assertEquals("ccc",al.get(2)); + assertEquals(3,al.size()); + } + + /** + * Test method for {@link com.coderising.array.ArrayList#add(int, java.lang.Object)}. + */ + @Test + public final void testAddIntObject() { + al.add("aaa"); + al.add(0,"bbb"); + al.add(1,"ccc"); + assertEquals("bbb",al.get(0)); + assertEquals("ccc",al.get(1)); + assertEquals("aaa",al.get(2)); + assertEquals(3,al.size()); + } + /** + * Test method for {@link com.coderising.array.ArrayList#add(int, java.lang.Object)}. + */ + @Test(expected=IndexOutOfBoundsException.class) + public final void testAddIntObjectWithException1() { + al.add(-1, "aaa"); + } + /** + * Test method for {@link com.coderising.array.ArrayList#add(int, java.lang.Object)}. + */ + @Test(expected=IndexOutOfBoundsException.class) + public final void testAddIntObjectWithException2() { + al.add("aaa"); + al.add(1,"bbb"); + } + + /** + * Test method for {@link com.coderising.array.ArrayList#get(int)}. + */ + @Test + public final void testGet() { + fail("Not yet implemented"); // TODO + } + /** + * Test method for {@link com.coderising.array.ArrayList#get(int)}. + */ + @Test + public final void testGetWithException1() { + fail("Not yet implemented"); // TODO + } + /** + * Test method for {@link com.coderising.array.ArrayList#get(int)}. + */ + @Test + public final void testGetWithException2() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.coderising.array.ArrayList#remove(int)}. + */ + @Test + public final void testRemove() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.coderising.array.ArrayList#size()}. + */ + @Test + public final void testSize() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.coderising.array.ArrayList#iterator()}. + */ + @Test + public final void testIterator() { + fail("Not yet implemented"); // TODO + } + +} diff --git a/group11/283091182/src/com/coding/basic/ArrayList.java b/group11/283091182/src/com/coding/basic/ArrayList.java deleted file mode 100644 index 402d05c019..0000000000 --- a/group11/283091182/src/com/coding/basic/ArrayList.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.coding.basic; - -import java.util.Arrays; - -public class ArrayList implements List { - - private int size = 0; - - private static final int GROW_BY_SIZE = 10; - - private Object[] elementData = new Object[GROW_BY_SIZE]; - - public void add(Object o){ - if(size == elementData.length){ - grow(); - } - elementData[size]=o; - size++; - } - public void add(int index, Object o){ - validate(index); - if(size == elementData.length){ - grow(); - } - for(int i=size;i>index+1;i--){ - elementData[i]=elementData[i-1]; - } - elementData[index]=o; - size++; - } - - public Object get(int index){ - validate(index); - return elementData[index]; - } - - public Object remove(int index){ - validate(index); - Object result = elementData[index]; - for(int i =index;i=size)throw new IndexOutOfBoundsException("Invalid Index:"+pos); - Object result = elementData[pos]; - pos++; - return result; - } - - - } - - private void grow(){ - elementData = Arrays.copyOf(elementData, elementData.length+GROW_BY_SIZE); - } - private void validate(int index){ - if(index<0||index>=size)throw new IndexOutOfBoundsException("Invalid Index:"+index); - } - - @Override - public String toString(){ - StringBuilder sb = new StringBuilder("["); - for(int i=0;i1)sb.append(","); - sb.append(elementData[i]); - } - sb.append("]size=").append(this.size()); - return sb.toString(); - } - - public static void main(String[] args){ - ArrayList l = new ArrayList(); - for(int i=0;i<12;i++){ - l.add(i+""); - } - System.out.println(l); - l.add("aaa"); - System.out.println("After adding aaa:"+l); - l.add(2,"bbb"); - System.out.println("After adding bbb:"+l); - System.out.println(l.get(2)); - System.out.println("After getting:"+l); - System.out.println(l.remove(2)); - System.out.println("After removing:"+l); - Iterator it = l.iterator(); - while(it.hasNext()){ - System.out.println(it.next()); - } - } - -} diff --git a/group11/283091182/src/com/coding/basic/ArrayListTest.java b/group11/283091182/src/com/coding/basic/ArrayListTest.java deleted file mode 100644 index 7807fa831e..0000000000 --- a/group11/283091182/src/com/coding/basic/ArrayListTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/** - * - */ -package com.coding.basic; - -import static org.junit.Assert.*; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * @author Administrator - * - */ -public class ArrayListTest { - - private ArrayList al; - /** - * @throws java.lang.Exception - */ - @BeforeClass - public static void setUpBeforeClass() throws Exception { - } - - /** - * @throws java.lang.Exception - */ - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - System.out.println("SetUp"); - al= new ArrayList(); - } - - /** - * @throws java.lang.Exception - */ - @After - public void tearDown() throws Exception { - System.out.println("TearDown"); - al = null; - } - - /** - * Test method for {@link com.coding.basic.ArrayList#add(java.lang.Object)}. - */ - @Test - public final void testAddObject() { - al.add("aaa"); - al.add("bbb"); - al.add("ccc"); - assertEquals("aaa",al.get(0)); - assertEquals("bbb",al.get(1)); - assertEquals("ccc",al.get(2)); - assertEquals(3,al.size()); - } - - /** - * Test method for {@link com.coding.basic.ArrayList#add(int, java.lang.Object)}. - */ - @Test - public final void testAddIntObject() { - al.add("aaa"); - al.add(0,"bbb"); - al.add(1,"ccc"); - assertEquals("bbb",al.get(0)); - assertEquals("ccc",al.get(1)); - assertEquals("aaa",al.get(2)); - assertEquals(3,al.size()); - } - /** - * Test method for {@link com.coding.basic.ArrayList#add(int, java.lang.Object)}. - */ - @Test(expected=IndexOutOfBoundsException.class) - public final void testAddIntObjectWithException1() { - al.add(-1, "aaa"); - } - /** - * Test method for {@link com.coding.basic.ArrayList#add(int, java.lang.Object)}. - */ - @Test(expected=IndexOutOfBoundsException.class) - public final void testAddIntObjectWithException2() { - al.add("aaa"); - al.add(1,"bbb"); - } - - /** - * Test method for {@link com.coding.basic.ArrayList#get(int)}. - */ - @Test - public final void testGet() { - fail("Not yet implemented"); // TODO - } - /** - * Test method for {@link com.coding.basic.ArrayList#get(int)}. - */ - @Test - public final void testGetWithException1() { - fail("Not yet implemented"); // TODO - } - /** - * Test method for {@link com.coding.basic.ArrayList#get(int)}. - */ - @Test - public final void testGetWithException2() { - fail("Not yet implemented"); // TODO - } - - /** - * Test method for {@link com.coding.basic.ArrayList#remove(int)}. - */ - @Test - public final void testRemove() { - fail("Not yet implemented"); // TODO - } - - /** - * Test method for {@link com.coding.basic.ArrayList#size()}. - */ - @Test - public final void testSize() { - fail("Not yet implemented"); // TODO - } - - /** - * Test method for {@link com.coding.basic.ArrayList#iterator()}. - */ - @Test - public final void testIterator() { - fail("Not yet implemented"); // TODO - } - -} diff --git a/group11/283091182/src/com/coding/basic/LinkedList.java b/group11/283091182/src/com/coding/basic/LinkedList.java deleted file mode 100644 index 233c243130..0000000000 --- a/group11/283091182/src/com/coding/basic/LinkedList.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.coding.basic; - -public class LinkedList implements List { - - private Node head = null; - private int size = 0; - - public void add(Object o){ - if(head==null){ - head = new Node(o); - }else{ - Node temp = head; - while(temp.hasNext()){ - temp = temp.next; - } - temp.next = new Node(o); - } - size++; - - } - public void add(int index , Object o){ - validate(index); - if(index==0){ - Node newNode = new Node(o,head); - head = newNode; - }else{ - Node temp = head; - for(int i=0;i=size)throw new IndexOutOfBoundsException("Invalid Index:"+index); - } - - private static class Node{ - Object data; - Node next; - public boolean hasNext(){ - return (this.next!=null); - } - public Node(Object data,Node next){ - this.data = data; - this.next = next; - } - public Node(Object data){ - this.data = data; - this.next = null; - } - } - @Override - public String toString(){ - StringBuilder sb = new StringBuilder("["); - Node temp = head; - while(temp!=null){ - if(sb.length()>1)sb.append(","); - sb.append(temp.data); - temp = temp.next; - } - sb.append("]size=").append(this.size()); - return sb.toString(); - } - public static void main(String[] args){ - LinkedList l = new LinkedList(); - for(int i=0;i<12;i++){ - l.add(i+""); - } - System.out.println(l); - l.add("aaa"); - System.out.println("After adding aaa:"+l); - l.add(2,"bbb"); - System.out.println("After adding bbb:"+l); - System.out.println(l.get(2)); - System.out.println("After getting:"+l); - System.out.println(l.remove(2)); - System.out.println("After removing:"+l); - l.addFirst("first"); - System.out.println("After add First:"+l); - l.addLast("last"); - System.out.println("After add Last:"+l); - System.out.println(l.removeFirst()); - System.out.println("After remove First:"+l); - System.out.println(l.removeLast()); - System.out.println("After remove Last:"+l); - Iterator it = l.iterator(); - while(it.hasNext()){ - System.out.println(it.next()); - } - //it.next(); - } -} diff --git a/group11/283091182/src/com/coding/basic/Queue.java b/group11/283091182/src/com/coding/basic/Queue.java index 45fea2a118..0f1f068e19 100644 --- a/group11/283091182/src/com/coding/basic/Queue.java +++ b/group11/283091182/src/com/coding/basic/Queue.java @@ -1,5 +1,7 @@ package com.coding.basic; +import com.coding.basic.linklist.LinkedList; + public class Queue { private LinkedList list = new LinkedList(); diff --git a/group11/283091182/src/com/coding/basic/Stack.java b/group11/283091182/src/com/coding/basic/Stack.java index 915d173b1b..5ff5ce5279 100644 --- a/group11/283091182/src/com/coding/basic/Stack.java +++ b/group11/283091182/src/com/coding/basic/Stack.java @@ -1,5 +1,7 @@ package com.coding.basic; +import com.coderising.array.ArrayList; + public class Stack { private ArrayList elementData = new ArrayList(); diff --git a/group11/283091182/src/com/coding/basic/linklist/LRUPageFrame.java b/group11/283091182/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..9f6edbcb66 --- /dev/null +++ b/group11/283091182/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,141 @@ +package com.coding.basic.linklist; + +/** + * 用双向链表实现LRU算法 + * @author liuxin + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + + Node(int pageNum, Node prev, Node next){ + this.pageNum = pageNum; + this.next = next; + this.prev = prev; + } + } + + private int capacity; + + private int size; + + + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + System.out.println("CurrentList= "+this.toString()+"; accessing - "+pageNum); + Node target = find(pageNum); + if(target==null){ + createNewNodeAsHead(pageNum); + }else{ + moveExistingNodeToHead(target); + } + + } + + private void removeLast(){ + Node secToLast = last.prev; + last = null; + secToLast.next = null; + last = secToLast; + size--; + } + + private void moveExistingNodeToHead(Node node){ + + Node prev = node.prev; + Node next = node.next; + + if(prev==null){ + //already in the head,do nothing; + return; + } + + if(next==null){ + //currently in the tail + last = prev; + } + + //in the middle + prev.next = next; + if(next!=null){ + next.prev = prev; + } + node.prev = null; + node.next = first; + first = node; + } + + private void createNewNodeAsHead(int value){ + Node node = new Node(value,null,null); + //first node + if(size==0){ + this.first = node; + this.last = node; + this.size ++; + }else{ + //linklist already exists + this.first.prev = node; + node.next = this.first; + this.first = node; + this.size++; + + if(size>capacity){ + removeLast(); + } + } + + } + + private Node find(int value){ + if(size==0){ + return null; + } + Node temp = first; + while(temp!=null){ + if(temp.pageNum==value){ + return temp; + }else{ + temp = temp.next; + } + } + return null; + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group11/283091182/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group11/283091182/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..4070f1f2b3 --- /dev/null +++ b/group11/283091182/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} diff --git a/group11/283091182/src/com/coding/basic/linklist/LinkedList.java b/group11/283091182/src/com/coding/basic/linklist/LinkedList.java new file mode 100644 index 0000000000..2c5959890a --- /dev/null +++ b/group11/283091182/src/com/coding/basic/linklist/LinkedList.java @@ -0,0 +1,181 @@ +package com.coding.basic.linklist; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +public class LinkedList implements List { + + private Node head = null; + private int size = 0; + + public void add(Object o){ + if(head==null){ + head = new Node(o); + }else{ + Node temp = head; + while(temp.hasNext()){ + temp = temp.next; + } + temp.next = new Node(o); + } + size++; + + } + public void add(int index , Object o){ + validate(index); + if(index==0){ + Node newNode = new Node(o,head); + head = newNode; + }else{ + Node temp = head; + for(int i=0;i=size)throw new IndexOutOfBoundsException("Invalid Index:"+index); + } + + private static class Node{ + Object data; + Node next; + public boolean hasNext(){ + return (this.next!=null); + } + public Node(Object data,Node next){ + this.data = data; + this.next = next; + } + public Node(Object data){ + this.data = data; + this.next = null; + } + } + @Override + public String toString(){ + StringBuilder sb = new StringBuilder("["); + Node temp = head; + while(temp!=null){ + if(sb.length()>1)sb.append(","); + sb.append(temp.data); + temp = temp.next; + } + sb.append("]size=").append(this.size()); + return sb.toString(); + } + public static void main(String[] args){ + LinkedList l = new LinkedList(); + for(int i=0;i<12;i++){ + l.add(i+""); + } + System.out.println(l); + l.add("aaa"); + System.out.println("After adding aaa:"+l); + l.add(2,"bbb"); + System.out.println("After adding bbb:"+l); + System.out.println(l.get(2)); + System.out.println("After getting:"+l); + System.out.println(l.remove(2)); + System.out.println("After removing:"+l); + l.addFirst("first"); + System.out.println("After add First:"+l); + l.addLast("last"); + System.out.println("After add Last:"+l); + System.out.println(l.removeFirst()); + System.out.println("After remove First:"+l); + System.out.println(l.removeLast()); + System.out.println("After remove Last:"+l); + Iterator it = l.iterator(); + while(it.hasNext()){ + System.out.println(it.next()); + } + //it.next(); + } +} diff --git a/group11/283091182/src/com/coding/basic/stack/Stack.java b/group11/283091182/src/com/coding/basic/stack/Stack.java new file mode 100644 index 0000000000..c59be3c1e4 --- /dev/null +++ b/group11/283091182/src/com/coding/basic/stack/Stack.java @@ -0,0 +1,50 @@ +package com.coding.basic.stack; + +import com.coderising.array.ArrayList; + +public class Stack { + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + elementData.add(o); + } + + public Object pop(){ + if(elementData.size()==0)throw new RuntimeException("Stack is empty."); + return elementData.remove(elementData.size()-1); + } + + public Object peek(){ + if(elementData.size()==0)throw new RuntimeException("Stack is empty."); + return elementData.get(elementData.size()-1); + } + public boolean isEmpty(){ + return (elementData.size()==0); + } + public int size(){ + return elementData.size(); + } + + @Override + public String toString(){ + return elementData.toString(); + } + + public static void main(String[] args){ + Stack s = new Stack(); + s.push("aaa"); + s.push("bbb"); + s.push("ccc"); + System.out.println(s); + System.out.println(s.isEmpty()); + System.out.println(s.size()); + System.out.println(s.peek()); + System.out.println(s.pop()); + System.out.println(s.pop()); + System.out.println(s.pop()); + System.out.println(s); + System.out.println(s.isEmpty()); + System.out.println(s.size()); + //System.out.println(s.pop()); + } +} diff --git a/group11/283091182/src/com/coding/basic/stack/StackUtil.java b/group11/283091182/src/com/coding/basic/stack/StackUtil.java new file mode 100644 index 0000000000..cd5aa08d06 --- /dev/null +++ b/group11/283091182/src/com/coding/basic/stack/StackUtil.java @@ -0,0 +1,140 @@ +package com.coding.basic.stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if(s==null || s.isEmpty()){ + return; + }; + Stack temp = new Stack(); + int counter = s.size(); + while(counter>1){ + //Get the peek one + Object o = s.pop(); + for(int i=0;is.size()){ + throw new RuntimeException("Index Out of Bound:"+ len); + } + Object[] objArr = new Object[len]; + Stack tmpStk = new Stack(); + for(int i=0;i totalLen){ + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + + return baos.toByteArray(); + } @Override diff --git a/group11/542194147/myDataStructure/src/com/coderising/jvm/loader/ClassFileLoader.java b/group11/542194147/myDataStructure/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..f6b93bfb41 --- /dev/null +++ b/group11/542194147/myDataStructure/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,89 @@ +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.Arrays; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + private static final int BUFFER_SIZE=1024; + + public byte[] readBinaryCode(String className) { + className=className.replace(".","\\")+".class"; + String absolutePath=null; + for(int i=0;ifile.length()){ + return Arrays.copyOf(baos.toByteArray(), (int) file.length()); + } + } catch (IOException e) { + e.printStackTrace(); + }finally{ + try { + fis.close(); + baos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return baos.toByteArray(); + } + + + public void addClassPath(String path) { + if(this.clzPaths.contains(path)){ + return; + } + clzPaths.add(path); + } + + + + public String getClassPath(){ + StringBuffer sb=new StringBuffer(); + for(int i=0;i=capacity){//缓存已满删除最后的数据 + removeLastNode(); + } + addNewNodeTOHead(newNode);//把新数据加到缓存头部 + } + } + + private void addNewNodeTOHead(Node node) { + if(first==null&&last==null){ + first=node; + last=node; + node.next=null; + node.prev=null; + }else{ + first.prev=node; + node.prev=null; + node.next=first; + first=node; + } + currentSize++; + } + + private void removeLastNode() { + Node node=last.prev; + node.next=null; + last.prev=null; + last=node; + currentSize--; + } + + private void moveExistingNodeToHead(Node node) { + if(node==first){ + return; + }else if(node==last){ + Node prevNode=node.prev; + last=prevNode; + prevNode.next=null; + }else{ + node.prev.next=node.next; + node.next.prev=node.prev; + } + node.prev=null; + node.next=first; + first.prev=node; + first=node; + } + + + private Node findNode(int data) { + Node node=first; + while(node!=null){ + if(node.pageNum==data){ + return node; + } + node=node.next; + } + return null; + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group11/542194147/myDataStructure/src/com/coding/basic/LRUPageFrameTest.java b/group11/542194147/myDataStructure/src/com/coding/basic/LRUPageFrameTest.java new file mode 100644 index 0000000000..53db234945 --- /dev/null +++ b/group11/542194147/myDataStructure/src/com/coding/basic/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding.basic; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} diff --git a/group11/996108220/src/com/coderising/jvm/clz/AccessFlag.java b/group11/996108220/src/com/coderising/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..faae056835 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.coderising.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group11/996108220/src/com/coderising/jvm/clz/ClassFile.java b/group11/996108220/src/com/coderising/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..8575f5641a --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,74 @@ +package com.coderising.jvm.clz; + +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + + System.out.println("Super Class Name:"+ getSuperClassName()); + + + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group11/996108220/src/com/coderising/jvm/clz/ClassIndex.java b/group11/996108220/src/com/coderising/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..f42e45d48f --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package com.coderising.jvm.clz; + +public class ClassIndex { + private int thisClassIndex;//u2 + private int superClassIndex;//u2 + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group11/996108220/src/com/coderising/jvm/constant/ClassInfo.java b/group11/996108220/src/com/coderising/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..d673cae1bd --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package com.coderising.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index ;//u2 + public ClassInfo(ConstantPool pool) { + super(pool); + } + public int getUtf8Index() { + return utf8Index; + } + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/ConstantInfo.java b/group11/996108220/src/com/coderising/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..466b072244 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/ConstantPool.java b/group11/996108220/src/com/coderising/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..86c0445695 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/FieldRefInfo.java b/group11/996108220/src/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..07133aa3a1 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex;//u2 + private int nameAndTypeIndex;//u2 + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/MethodRefInfo.java b/group11/996108220/src/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..ad3723ad0c --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; //u2 + private int nameAndTypeIndex;//u2 + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/NameAndTypeInfo.java b/group11/996108220/src/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..ee05963d21 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1;//u2 + private int index2;//u2 + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/NullConstantInfo.java b/group11/996108220/src/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..936736016f --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/StringInfo.java b/group11/996108220/src/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..1f0539dda4 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index;//u2 + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group11/996108220/src/com/coderising/jvm/constant/UTF8Info.java b/group11/996108220/src/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..c2c4408421 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ;//2 + private String value;//length + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group11/996108220/src/com/coderising/jvm/loader/ByteCodeIterator.java b/group11/996108220/src/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..a151decad8 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,51 @@ +package com.coderising.jvm.loader; + +import java.util.Arrays; +import com.coderising.jvm.util.Util; + + + +public class ByteCodeIterator { + byte[] codes; + int cursor=0; + public ByteCodeIterator(byte[] codes) { + this.codes=codes; + } + public ByteCodeIterator(byte[] codes,int cursor) { + this.codes=codes; + this.cursor=cursor; + } + public boolean hasNext() { + return cursor != codes.length; + } + + + public int next() { + + int i = cursor; + if (i >= codes.length) + throw new ArrayIndexOutOfBoundsException(); + cursor = i + 1; + return codes[i]&0xFF; + } + public int nextU2ToInt() { + + return Util.byteToInt(new byte[]{codes[cursor++],codes[cursor++]}); + } + public int nextU4ToInt() { + + return Util.byteToInt(new byte[]{codes[cursor++],codes[cursor++], + codes[cursor++],codes[cursor++]}); + } + public String nextU4ToHexString() { + return Util.byteToHexString(new byte[]{codes[cursor++],codes[cursor++], + codes[cursor++],codes[cursor++]}); + + } + public byte[] getByte(int length) { + int i=cursor; + cursor=cursor+length; + return Arrays.copyOfRange(codes,i, cursor); + } + +} diff --git a/group11/996108220/src/com/coderising/jvm/loader/ClassFileLoader.java b/group11/996108220/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..eccf6dc7b0 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,88 @@ +package com.coderising.jvm.loader; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import com.coderising.jvm.clz.ClassFile; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + className = className.replace('.', File.separatorChar) +".class"; + + for(String path : this.clzPaths){ + + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if(codes != null){ + return codes; + } + } + + return null; + + } + + private byte[] loadClassFile(String fileName) { + ArrayList list=new ArrayList(); + try { + InputStream in=new FileInputStream(fileName.toString()); + int length=-1; + byte[] buffer=new byte[1024]; + while ((length=in.read(buffer))!=-1) { + int size=list.size(); + for (int i = size; i < size+length; i++) { + list.add(buffer[i-size]); + } + } + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + byte[] byteCodes=new byte[list.size()]; + for (int i = 0; i < byteCodes.length; i++) { + byteCodes[i]=list.get(i); + } + + return byteCodes; + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + public void addClassPath(String path) { + clzPaths.add(path); + + } + + + + public String getClassPath(){ + String string=""; + for (int i = 0; i < clzPaths.size(); i++) { + string=i==0?string+clzPaths.get(i):string+";"+clzPaths.get(i); + } + return string; + } + + + + + +} diff --git a/group11/996108220/src/com/coderising/jvm/loader/ClassFileParser.java b/group11/996108220/src/com/coderising/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..ac55f25e0e --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/loader/ClassFileParser.java @@ -0,0 +1,111 @@ +package com.coderising.jvm.loader; +import com.coderising.jvm.clz.AccessFlag; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.FieldRefInfo; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.NullConstantInfo; +import com.coderising.jvm.constant.StringInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.util.Util; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + ByteCodeIterator iter=new ByteCodeIterator(codes); + String magicNumber=iter.nextU4ToHexString(); + if (!magicNumber.equals("cafebabe")) { + return null; + } + ClassFile classFile=new ClassFile(); + classFile.setMinorVersion(iter.nextU2ToInt()); + classFile.setMajorVersion(iter.nextU2ToInt()); + classFile.setConstPool(parseConstantPool(iter)); + classFile.setAccessFlag(parseAccessFlag(iter)); + classFile.setClassIndex(parseClassInfex(iter)); + return classFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + + return new AccessFlag(iter.nextU2ToInt()); + } + + private ClassIndex parseClassInfex(ByteCodeIterator iter) { + ClassIndex classIndex=new ClassIndex(); + classIndex.setThisClassIndex(iter.nextU2ToInt()); + classIndex.setSuperClassIndex(iter.nextU2ToInt()); + return classIndex; + + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + int constPoolCount=iter.nextU2ToInt(); + + ConstantPool pool=new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); + for (int i = 1; i <= constPoolCount-1; i++) { + int tag=iter.next(); + if (tag==1) { + //UTF8Info + UTF8Info utf8Info=new UTF8Info(pool); + int length=iter.nextU2ToInt(); + utf8Info.setLength(length); + String value=Util.byteToString(iter.getByte(length)); + utf8Info.setValue(value); + pool.addConstantInfo(utf8Info); + } + else if (tag==7) { + //ClassInfo + ClassInfo classInfo=new ClassInfo(pool); + int utf8Index=iter.nextU2ToInt(); + classInfo.setUtf8Index(utf8Index); + pool.addConstantInfo(classInfo); + } + else if (tag==8) { + //StringInfo + StringInfo stringInfo=new StringInfo(pool); + int index=iter.nextU2ToInt(); + stringInfo.setIndex(index); + pool.addConstantInfo(stringInfo); + } + else if (tag==9) { + //FieldRefInfo + FieldRefInfo fieldRefInfo=new FieldRefInfo(pool); + int classInfoIndex=iter.nextU2ToInt(); + int nameAndTypeIndex=iter.nextU2ToInt(); + fieldRefInfo.setClassInfoIndex(classInfoIndex); + fieldRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + pool.addConstantInfo(fieldRefInfo); + } + else if (tag==10) { + //MethodRefInfo + MethodRefInfo methodRefInfo=new MethodRefInfo(pool); + int classInfoIndex=iter.nextU2ToInt(); + int nameAndTypeIndex=iter.nextU2ToInt(); + methodRefInfo.setClassInfoIndex(classInfoIndex); + methodRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + pool.addConstantInfo(methodRefInfo); + } + else if (tag==12) { + //NameAndTypeInfo + NameAndTypeInfo nameAndTypeInfo=new NameAndTypeInfo(pool); + int index1=iter.nextU2ToInt(); + int index2=iter.nextU2ToInt(); + nameAndTypeInfo.setIndex1(index1); + nameAndTypeInfo.setIndex2(index2); + pool.addConstantInfo(nameAndTypeInfo); + } + else { + new RuntimeException("缺少tag为"+tag+"的常量"); + } + } + + return pool; + } + + +} diff --git a/group11/996108220/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group11/996108220/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..44d000a19a --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,201 @@ +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.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.loader.ClassFileLoader; + + + + + +public class ClassFileloaderTest { + + + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; + + static String path1 = "F:\\mycoding2017\\group11\\996108220\\bin"; + static String path2 = "C:\temp"; + + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + + clzFile = loader.loadClass(className); + //clzFile.print(); + } + + + @Before + 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", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + + +} diff --git a/group11/996108220/src/com/coderising/jvm/test/EmployeeV1.java b/group11/996108220/src/com/coderising/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..9a36573dd3 --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/test/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.coderising.jvm.test; + +public class EmployeeV1 { + + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + public void setAge(int age){ + this.age = age; + } + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + public static void main(String[] args){ + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group11/996108220/src/com/coderising/jvm/util/Util.java b/group11/996108220/src/com/coderising/jvm/util/Util.java new file mode 100644 index 0000000000..c9808b1c1c --- /dev/null +++ b/group11/996108220/src/com/coderising/jvm/util/Util.java @@ -0,0 +1,33 @@ +package com.coderising.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes){ + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;ielementData.length)this.grow(elementData); - else elementData[size++]=o; + else{ + elementData[size]=o; + size++; + } + } /** * 在index处添加元素,index+1到size-1元素向后移动 diff --git a/group11/996108220/src/com/coding/basic/Stack.java b/group11/996108220/src/com/coding/basic/Stack.java deleted file mode 100644 index ea41c87d1b..0000000000 --- a/group11/996108220/src/com/coding/basic/Stack.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.coding.basic; - -public class Stack { - //用动态数组实现栈 - private ArrayList elementData = new ArrayList(); - - public void push(Object o){ - elementData.add(elementData.size()); - } - - public Object pop(){ - return elementData.remove(elementData.size()-1); - } - - public Object peek(){ - return elementData.get(elementData.size()-1); - } - public boolean isEmpty(){ - return elementData.size()==0?true:false; - } - public int size(){ - return elementData.size(); - } -} diff --git a/group11/996108220/src/com/coding/basic/linklist/LRUPageFrame.java b/group11/996108220/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..f9ee1e68fa --- /dev/null +++ b/group11/996108220/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,139 @@ +package com.coding.basic.linklist; + + +/** + * 用双向链表实现LRU算法 + * @author 996108220 + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + + public Node(int pageNum2) { + this.pageNum=pageNum2; + this.next=null; + this.prev=null; + } + + } + + private int capacity; + private int size; + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + this.size=0; + + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + Node node=remove(pageNum); + if (node==null) { + node=new Node(pageNum); + push(node); + } + else { + addTail(node); + } + + + } + + + private void push(Node node) { + if (this.size()==capacity) { + removeFirst(); + } + addTail(node); + } + + private void addTail(Node node) { + if (size==0) { + first=node; + last=node; + } + else { + node.prev=last; + last.next=node; + last=node; + + } + size++; + + } + + private void removeFirst() { + + Node node=this.first; + first=first.next; + node.next=null; + first.prev=null; + size--; + } + + private int size() { + + return size; + } + + private Node remove(int pageNum) { + Node node=first; + while(node!=null){ + if (node.pageNum==pageNum) { + if (node==first) { + first=node.next; + node.next=null; + first.prev=null; + } + else if (node==last) { + last=node.prev; + last.next=null; + node.prev=null; + } + else { + node.prev.next=node.next; + node.next.prev=node.prev; + node.next=null; + node.prev=null; + } + size--; + break; + } + node=node.next; + } + return node; + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = last; + while(node != null){ + buffer.append(node.pageNum); + + node = node.prev; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group11/996108220/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group11/996108220/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..67cf36067b --- /dev/null +++ b/group11/996108220/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} diff --git a/group11/996108220/src/com/coding/basic/stack/Stack.java b/group11/996108220/src/com/coding/basic/stack/Stack.java new file mode 100644 index 0000000000..05f380a304 --- /dev/null +++ b/group11/996108220/src/com/coding/basic/stack/Stack.java @@ -0,0 +1,40 @@ +package com.coding.basic.stack; + +import com.coding.basic.ArrayList; + +public class Stack { + //用动态数组实现栈 + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + elementData.add(o); + } + + public Object pop(){ + return elementData.remove(elementData.size()-1); + } + + public Object peek(){ + return elementData.get(elementData.size()-1); + } + public boolean isEmpty(){ + return elementData.size()==0?true:false; + } + public int size(){ + return elementData.size(); + } + public String toString() { + + StringBuffer buffer=new StringBuffer("["); + for (int i = elementData.size()-1; i >=0; i--) { + if (i==0) { + buffer.append(elementData.get(i).toString()+"]"); + } + else { + buffer.append(elementData.get(i).toString()+","); + } + } + return buffer.toString(); + } + +} diff --git a/group11/996108220/src/com/coding/basic/stack/StackUtil.java b/group11/996108220/src/com/coding/basic/stack/StackUtil.java new file mode 100644 index 0000000000..2499f144ea --- /dev/null +++ b/group11/996108220/src/com/coding/basic/stack/StackUtil.java @@ -0,0 +1,131 @@ +package com.coding.basic.stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + + reverse(s,s.size()); + } + + private static void reverse(Stack s, int length) { + if (length==1) { + return ; + } + Stack s1=new Stack(); + Object o=s.pop(); + for (int i = 1; i < length; i++) { + s1.push(s.pop()); + } + s.push(o); + for (int i = 1; i < length; i++) { + s.push(s1.pop()); + } + reverse(s, length-1); + + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if (s.size()==0) { + return; + } + Stack s1=new Stack(); + while(s.size()!=0) { + if (!s.peek().equals(o)) { + s1.push(s.pop()); + + } + else { + s.pop(); + break; + } + } + while(s1.size()!=0) { + s.push(s1.pop()); + } + + + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if (len>s.size()||len<=0) { + return null; + } + Stack s1=new Stack(); + Object[] array=new Object[len]; + for (int i = 0; i < len; i++) { + Object object=s.pop(); + array[i]=object; + s1.push(object); + } + while(s1.size()!=0) { + s.push(s1.pop()); + } + return array; + } + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * @param s + * @return + */ + public static boolean isValidPairs(String s){ + Stack stack=new Stack(); + for (int i = 0; i < s.length(); i++) { + switch (s.charAt(i)) { + case '(': + stack.push(s.charAt(i)); + break; + case '[': + stack.push(s.charAt(i)); + break; + case '{': + stack.push(s.charAt(i)); + break; + case ')': + if (stack.size()==0||(!stack.pop().equals('('))) { + return false; + } + break; + case ']': + if (stack.size()==0||(!stack.pop().equals('['))) { + return false; + } + break; + case '}': + if (stack.size()==0||(!stack.pop().equals('{'))) { + return false; + } + break; + default: + break; + } + } + if (stack.size()!=0) { + return false; + } + else { + return true; + } + + } + + +} diff --git a/group11/996108220/src/com/coding/basic/stack/StackUtilTest.java b/group11/996108220/src/com/coding/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..91e3211683 --- /dev/null +++ b/group11/996108220/src/com/coding/basic/stack/StackUtilTest.java @@ -0,0 +1,82 @@ +package com.coding.basic.stack; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class StackUtilTest { + Stack s; + @Before + public void setUp() throws Exception { + + } + + @After + public void tearDown() throws Exception { + } + @Test + public void testToString() { + s=new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + s.push(6); + + Assert.assertEquals("[6,5,4,3,2,1]", s.toString()); + } + + @Test + public void testReverse() { + s=new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + s.push(6); + StackUtil.reverse(s); + //System.out.println(s.size()); + Assert.assertEquals("[1,2,3,4,5,6]", s.toString()); + } + @Test + public void testRemove() { + s=new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + s.push(6); + StackUtil.remove(s, 6); + //System.out.println(s.toString()); + Assert.assertEquals("[5,4,3,2,1]", s.toString()); + } + @Test + public void testGetTop() { + s=new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + s.push(6); + Object[] s1=StackUtil.getTop(s, s.size()); + for (int i = 0; i < s1.length; i++) { + System.out.println(s1[i]); + } + //Assert.assertEquals("[5,6]", s1.toString()); + } + @Test + public void testIsValidPairs() { + String s="([e{df])" ; + Assert.assertEquals(false, StackUtil.isValidPairs(s)); + } + +} diff --git a/group11/group11.md b/group11/group11.md deleted file mode 100644 index 8b13789179..0000000000 --- a/group11/group11.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/group12/247565311/structure/week1/ArrayList.java b/group12/247565311/structure/week1/ArrayList.java new file mode 100644 index 0000000000..a16c32e05c --- /dev/null +++ b/group12/247565311/structure/week1/ArrayList.java @@ -0,0 +1,204 @@ +package structure.week1; + +import java.util.Collection; + +import structure.week1.List; + +public class ArrayList{ + private int size=0,offset=10; + private Object[] data = null; + public ArrayList(){ + data = new Object[offset]; + } + public ArrayList(int arg0){ + if(arg0<0) arg0=0; + size = arg0; + data = new Object[size]; + } + + public void add(Object arg0) { + size += 1; + int leng = data.length; + if(size>leng){ + Object[] newdata = new Object[size + offset]; + for(int i=0;isize || 0leng){ + Object[] newdata = new Object[size + offset]; + for(int i=0;i arg0) { + if (arg0 == null) return false; + int leng = data.length,newobjnum = arg0.size(),lastsize=size; + size += newobjnum; + if(size>leng){ + Object[] newdata = new Object[size + offset]; + for(int i=0;i arg1) { + int newobjnum = arg1.size(),lastsize = size; + if(arg1 == null || arg0>size+1 || 0>arg0 || newobjnum==0) return false; + size += newobjnum; + int leng = data.length; + if(size>leng){ + Object[] newdata = new Object[size + offset]; + for(int i=0;i arg0) { + for(Object o:arg0){ + if(!this.contains(o)) return false; + } + return true; + } + + public E get(int arg0) { + if(arg0 >-1 && arg0-1;i--){ + if(this.data[i].equals(arg0)) return i; + } + return -1; + } + + public Iterator iterator() { + + return null; + } + + public boolean remove(Object arg0) { + for(int i=0;ithis.size-1) return null; + E res = (E)data[arg0]; + for(int i=arg0;i arg0) { + int toberemovednums = arg0.size(); + if(!this.containsAll(arg0)) return false; + int index=0; + for(int i=0;ithis.size-1) return null; + this.data[arg0] = arg1; + return arg1; + } + + public int size() { + return this.size; + } +////////////////////////////////////////////// + public Object[] toArray() { + if(this.size == 0) return null; + Object[] res = new Object[this.size]; + for(int i=0;i T[] toArray(T[] arg0) { + T[] res = (T[])(new Object[this.size]); + for(int i=0;i{ + public boolean hasNext(); + public E next(); +} diff --git a/group12/247565311/structure/week1/LinkedList.java b/group12/247565311/structure/week1/LinkedList.java new file mode 100644 index 0000000000..362959879b --- /dev/null +++ b/group12/247565311/structure/week1/LinkedList.java @@ -0,0 +1,237 @@ +package structure.week1; + +import java.util.Collection; + +public class LinkedList { + private Node head = null; + private Node tail = null; + private int size = 0; + + public LinkedList(){ + head = new Node(null); + tail = new Node(null); + head.next = tail; + tail.ahead = head; + size = 0; + } + public LinkedList(int arg0){ + head = new Node(null); + tail = new Node(null); + head.next = tail; + tail.ahead = head; + size = 0; + } + public Object clone(){ + LinkedList clone = null; + try { + clone = (LinkedList)(super.clone()); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + clone.head = new Node(null); + clone.tail = new Node(null); + clone.size = 0; + for(Node x = head.next;x!=null;x = x.next){ + clone.add(x.val); + } + return clone; + } + public void add(Object val) { + Node n = new Node(val); + n.next = tail; + n.ahead = tail.ahead; + tail.ahead.next = n; + tail.ahead = n; + size += 1; + } + + public void add(int arg0, E arg1) { + if(arg0<0 || arg0>size) arg0=0; + Node n=new Node(arg1),p=head; + for(int i=0;i arg0) { + for(E o:arg0){ + this.add(o); + } + return true; + } + + public boolean addAll(int arg0, Collection arg1) { + for(E e:arg1){ + this.add(arg0,e); + arg0+=1; + } + return true; + } + + public void clear() { + head = new Node(null); + tail = new Node(null); + head.next = tail; + tail.ahead = head; + size = 0; + } + + public boolean contains(Object arg0) { + boolean flag = arg0==null; + Node n = head; + for(int i=0;i arg0) { + for(Object e:arg0){ + if(!this.contains(e)) return false; + } + return true; + } + + public E get(int arg0) { + E res = null; + if(arg0>-1 && arg0 < size){ + Node n = head; + for(int i=0;i iterator() { + + return null; + } + + public int lastIndexOf(Object arg0) { + boolean flag = arg0==null; + Node n = tail; + for(int i=size-1;i>-1;i--){ + n = n.ahead; + if(flag){ + if(n.val == null) return i; + }else{ + if(arg0.equals(n.val)) return i; + } + } + return -1; + } + + public boolean remove(Object arg0) { + Node n = head; + int index = this.indexOf(arg0); + if(index == -1) return false; + for(int i=0;isize-1) return null; + for(int i=0;i arg0) { + for(Object o:arg0){ + if(!this.remove(o)) return false; + } + return true; + } + + public boolean retainAll(Collection arg0) { + // ? + return false; + } + + public E set(int arg0, E arg1) { + if(arg0<0 || arg0>size-1) return null; + Node n=head; + for(int i=0;i T[] toArray(T[] arg0) { + T[]res = (T[]) new Object[size]; + Node n = head; + for(int i=0;i extends Iterator{ + public void add(Object o); + public E get(int index); + public E remove(int index); + public int size(); + void add(int arg0, E arg1); +} diff --git a/group12/247565311/structure/week1/Queue.java b/group12/247565311/structure/week1/Queue.java new file mode 100644 index 0000000000..ec96650332 --- /dev/null +++ b/group12/247565311/structure/week1/Queue.java @@ -0,0 +1,18 @@ +package structure.week1; +public class Queue { + private LinkedList data = new LinkedList(); + public void enQueue(E arg0){ + data.add(data.size(),arg0); + } + public E deQueue(){ + E res = data.get(0); + data.remove(0); + return res; + } + public int size(){ + return data.size(); + } + public boolean isEmpty(){ + return data.isEmpty(); + } +} diff --git a/group12/247565311/structure/week1/Stack.java b/group12/247565311/structure/week1/Stack.java new file mode 100644 index 0000000000..582f5d0eac --- /dev/null +++ b/group12/247565311/structure/week1/Stack.java @@ -0,0 +1,28 @@ +package structure.week1; + +import structure.week1.List; + +public class Stack { + private ArrayList data = new ArrayList(); + public boolean isEmpty(){ + return data.isEmpty(); + } + public int size(){ + return data.size(); + } + public boolean push(E arg0){ + data.add(arg0); + return true; + } + public E pop(){ + if(this.isEmpty()) return null; + E res = data.get(data.size()-1); + data.remove(data.size()-1); + return res; + } + public E peek(){ + if(this.isEmpty()) return null; + E res = data.get(data.size()-1); + return res; + } +} diff --git a/group12/247565311/structure/week2/ArrayUtil.java b/group12/247565311/structure/week2/ArrayUtil.java new file mode 100644 index 0000000000..4c29f58e7e --- /dev/null +++ b/group12/247565311/structure/week2/ArrayUtil.java @@ -0,0 +1,206 @@ +package structure.week2; +import structure.week1.ArrayList; + +public class ArrayUtil { + + /** + * ����һ����������a , �Ը������ֵ�����û� + ���磺 a = [7, 9 , 30, 3] , �û���Ϊ [3, 30, 9,7] + ��� a = [7, 9, 30, 3, 4] , �û���Ϊ [4,3, 30 , 9,7] + * @param origin + * @return + */ + public void reverseArray(int[] origin){ // time :O(n) + int leno = origin.length; + for(int i=0;i=len1){ + temparray[temp] = array2[p2]; + p2 += 1; + continue; + } + if(p2>=len2){ + temparray[temp] = array1[p1]; + p1 += 1; + continue; + } + if(array1[p1] > array2[p2]){ + temparray[temp] = array2[p2]; + p2 += 1; + }else{ + temparray[temp] = array1[p1]; + p1 += 1; + } + } + temp = 0; + for(int i=1;i data = new ArrayList(); + data.add(llast); + data.add(last); + while(last+llast li = new ArrayList(); + int cur = 2; + while(cur li = null,resli = new ArrayList(); + for(int i=6;i getAllElem(int arg0){ + ArrayList res = new ArrayList(); + for(int i=1;i size || index<0) throw new IndexOutOfBoundsException("Index:"+index+", Size:"+size); + } + private void checkGetIndex(int index){ + if(index >= size || index<0) throw new IndexOutOfBoundsException("Index:"+index+", Size:"+size); + } + public void add(Object o){ + Node newNode = new Node(o),p = head; + while(p.next!=null) + p = p.next; + p.next = newNode; + size += 1; + } + /** + * + * */ + public void add(int index , Object o){ + checkAddIndex(index); + Node p = head; + for(int i=0;i7->10 , ���ú��Ϊ 10->7->3 + */ + public void reverse(){ + Node rhead = new Node(),p=head; + for(int i=0;i5->7->8 , ɾ���Ժ��ֵΪ 7->8 + * ���list = 2->5->7->8->10 ,ɾ���Ժ��ֵΪ7,8,10 + + */ + public void removeFirstHalf(){ + int numToRemove = size/2; + for(int i=0;i101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * ���صĽ��Ӧ����[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int []res = new int[list.size()]; + Node p = head.next,q = list.head.next; + int lenl = list.size(),index=0; + for(int i=0;imax) return; // Ŀ������ (min,max) + Node p = head; + while(p.next != null && ((Integer)p.next.data).intValue()<=min) // ��������ɵ�Ԫ�� + p = p.next; + while(p.next != null && ((Integer)p.next.data).intValue() lib = new HashSet(); + class Node{ + int val; + Node next; + public Node(int _val){ + val = _val; + next = null; + } + } + public LRUPageFrame(int _size){ + if(_size>0) { + this.size = _size; + } + } + public int[] getAll(){ + int length = lib.size(),index = 0; + int []res = new int[length]; + Node p = head.next; + while(p!=null){ + res[index] = p.val; + index += 1; + p = p.next; + } + return res; + } + public void add(int e){ + int index = 0; + if(lib.contains(e)){ + Node p = head; + while(p.next!= null){ + if(p.next.val == e){ + Node newn = p.next; + p.next = newn.next; + newn.next = head.next; + head.next = newn; + break; + } + p = p.next; + } + }else{ + if(lib.size() == size){ + lib.add(e); + Node newn = new Node(e); + newn.next = head.next; + head.next = newn; + Node p = head; + while(p.next.next != null) + p = p.next; + Node deln = p.next; + lib.remove(deln.val); + p.next = null; + }else{ + Node newn = new Node(e); + newn.next = head.next; + head.next = newn; + lib.add(e); + } + } + } +} diff --git a/group12/247565311/structure/week5/LRUPageFrameTest.java b/group12/247565311/structure/week5/LRUPageFrameTest.java new file mode 100644 index 0000000000..cb795054d5 --- /dev/null +++ b/group12/247565311/structure/week5/LRUPageFrameTest.java @@ -0,0 +1,36 @@ +package structure. week5; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class LRUPageFrameTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAdd() { + LRUPageFrame lru = new LRUPageFrame(5); + lru.add(3); + lru.add(7); + lru.add(5); + lru.add(8); + lru.add(10); + Assert.assertArrayEquals(new int[]{10,8,5,7,3}, lru.getAll()); + lru.add(5); + lru.add(3); + Assert.assertArrayEquals(new int[]{3,5,10,8,7}, lru.getAll()); + lru.add(8); + lru.add(11); + Assert.assertArrayEquals(new int[]{11,8,3,5,10}, lru.getAll()); + } +} diff --git a/group12/247565311/structure/week6/StackUtil.java b/group12/247565311/structure/week6/StackUtil.java new file mode 100644 index 0000000000..9895f02f30 --- /dev/null +++ b/group12/247565311/structure/week6/StackUtil.java @@ -0,0 +1,133 @@ +package structure.week6; +import java.util.Stack; +public class StackUtil { + + public static void bad_reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack(); + while(!s.isEmpty()){ + tmpStack.push(s.pop()); + } + s = tmpStack; + } + + /** + * 閸嬪洩顔曢弽鍫滆厬閻ㄥ嫬鍘撶槐鐘虫ЦInteger, 娴犲孩鐖ゆい璺哄煂閺嶅牆绨抽弰锟� 5,4,3,2,1 鐠嬪啰鏁ょ拠銉︽煙濞夋洖鎮楅敍锟介崗鍐濞嗏�绨崣妯硅礋: 1,2,3,4,5 + * 濞夈劍鍓伴敍姘涧閼虫垝濞囬悽鈯縯ack閻ㄥ嫬鐔�張顒佹惙娴f粣绱濋崡纭僽sh,pop,peek,isEmpty閿涳拷閸欘垯浜掓担璺ㄦ暏閸欙箑顦绘稉锟介嚋閺嶅牊娼垫潏鍛И + */ + public static void reverse(Stack s){ + if(s == null || s.isEmpty()) return; + int size = 0; + Stack s1 = new Stack(); + while(!s.isEmpty()){ + s1.push(s.pop()); + size += 1; + } + while(!s1.isEmpty()) + s.push(s1.pop()); + for(int i=0;ii) + s1.push(s.pop()); + s.push(integer); + while(s1.size()>0) + s.push(s1.pop()); + } + } + // 閫氳繃閫掑綊鍙互涓嶄娇鐢ㄥ爢鏍堝畬鎴愯繖涓�姛鑳� + public static void reverse2(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Integer top = s.pop(); + reverse(s); + addToBottom(s,top); + } + public static void addToBottom(Stack s, Integer value){ + if(s.isEmpty()){ + s.push(value); + } else{ + Integer top = s.pop(); + addToBottom(s,value); + s.push(top); + } + } + /** + * 閸掔娀娅庨弽鍫滆厬閻ㄥ嫭鐓囨稉顏勫帗缁憋拷濞夈劍鍓伴敍姘涧閼虫垝濞囬悽鈯縯ack閻ㄥ嫬鐔�張顒佹惙娴f粣绱濋崡纭僽sh,pop,peek,isEmpty閿涳拷閸欘垯浜掓担璺ㄦ暏閸欙箑顦绘稉锟介嚋閺嶅牊娼垫潏鍛И + * + * @param o + */ + public static void remove(Stack s,Object o) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack(); + while(!s.isEmpty()){ + Object value = s.pop(); + if(!value.equals(o)){ + tmpStack.push(value); + } + } + while(!tmpStack.isEmpty()){ + s.push(tmpStack.pop()); + } + } + + /** + * 娴犲孩鐖ゆい璺哄絿瀵版en娑擃亜鍘撶槐锟�閸樼喐娼甸惃鍕垽娑擃厼鍘撶槐鐘辩箽閹镐椒绗夐崣锟� * 濞夈劍鍓伴敍姘涧閼虫垝濞囬悽鈯縯ack閻ㄥ嫬鐔�張顒佹惙娴f粣绱濋崡纭僽sh,pop,peek,isEmpty閿涳拷閸欘垯浜掓担璺ㄦ暏閸欙箑顦绘稉锟介嚋閺嶅牊娼垫潏鍛И + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if(s == null || s.isEmpty() || s.size() stack = new Stack(); + for(int i=0;i s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + + StackUtil.addToBottom(s, 0); + + Assert.assertEquals("[0, 1, 2, 3]", s.toString()); + + } + @Test + public void testReverse() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString()); + StackUtil.reverse(s); + Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString()); + } + + @Test + public void testRemove() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + StackUtil.remove(s, 2); + Assert.assertEquals("[1, 3]", s.toString()); + } + + @Test + public void testGetTop() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + { + Object[] values = StackUtil.getTop(s, 3); + Assert.assertEquals(5, values[0]); + Assert.assertEquals(4, values[1]); + Assert.assertEquals(3, values[2]); + } + } + + @Test + public void testIsValidPairs() { + Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])")); + Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})")); + } + +} \ No newline at end of file diff --git a/group12/247565311/structure/week7/InfixExpr.java b/group12/247565311/structure/week7/InfixExpr.java new file mode 100644 index 0000000000..4fc4d13fbe --- /dev/null +++ b/group12/247565311/structure/week7/InfixExpr.java @@ -0,0 +1,99 @@ +package structure.week7; +// 姹傝В琛ㄨ揪寮忓瓧绗︿覆锛岄鍏堝皢琛ㄨ揪寮忓垱寤烘垚涓�5琛ㄨ揪寮忔爲锛岄渶瑕佹牴鎹繍绠楃鐨勪紭鍏堢骇鏉ュ垱寤� +public class InfixExpr { + String expr = null; + Element getElem = null; + public InfixExpr(String expr) { + this.expr = expr; + getElem = new Element(expr); + } + public float evaluate() throws Exception{ + Node node = new Node('\0',getElem.getNextNum()); + Node root = createNode(node); + return (float) getValue(root); + } + class Element{ + private int index; + private String str; + public Element(String _str){ + index = 0; + str = _str; + } + public double getNextNum(){ + double resl = 0,resr=0; + int fbits = 0; + char ch = str.charAt(index); + boolean hasp = false; + while(ch=='.' || (ch<='9' && '0'<=ch)){ + index += 1; + if(ch == '.') hasp = true; + else{ + if(hasp){ + fbits -= 1; + resr += (double)(ch-'0') * Math.pow(10,fbits); + }else{ + resl *= 10; + resl += (ch-'0'); + } + } + if(hasNext()) ch = str.charAt(index); + else break; + } + return resl+resr; + } + public char getNextOper(){ + if(hasNext()){ + char ch = str.charAt(index); + if((ch>='0' && '9'>=ch) || ch=='.') return '\0'; + else{ + index += 1; + return ch; + } + }else{ + return '\0'; + } + } + public boolean hasNext(){ + return index implements List { - private int size=0,offset=10; - private Object[] data = null; - public ArrayList(){ - data = new Object[offset]; - } - public ArrayList(int arg0){ - if(arg0<0) arg0=0; - size = arg0; - data = new Object[size]; - } - @Override - public void add(Object arg0) { - size += 1; - int leng = data.length; - if(size>leng){ - Object[] newdata = new Object[size + offset]; - for(int i=0;isize || 0leng){ - Object[] newdata = new Object[size + offset]; - for(int i=0;i arg0) { - if (arg0 == null) return false; - int leng = data.length,newobjnum = arg0.size(),lastsize=size; - size += newobjnum; - if(size>leng){ - Object[] newdata = new Object[size + offset]; - for(int i=0;i arg1) { - int newobjnum = arg1.size(),lastsize = size; - if(arg1 == null || arg0>size+1 || 0>arg0 || newobjnum==0) return false; - size += newobjnum; - int leng = data.length; - if(size>leng){ - Object[] newdata = new Object[size + offset]; - for(int i=0;i arg0) { - for(Object o:arg0){ - if(!this.contains(o)) return false; - } - return true; - } - - @Override - public E get(int arg0) { - if(arg0 >-1 && arg0-1;i--){ - if(this.data[i].equals(arg0)) return i; - } - return -1; - } - - public Iterator iterator() { - - return null; - } - - public boolean remove(Object arg0) { - for(int i=0;ithis.size-1) return null; - E res = (E)data[arg0]; - for(int i=arg0;i arg0) { - int toberemovednums = arg0.size(); - if(!this.containsAll(arg0)) return false; - int index=0; - for(int i=0;ithis.size-1) return null; - this.data[arg0] = arg1; - return arg1; - } - - @Override - public int size() { - return this.size; - } - - public List subList(int arg0, int arg1) { - if(arg0>=arg1 || arg0<0 || arg1>this.size-1) return null; - List res = new ArrayList(); - for(int i=arg0;i T[] toArray(T[] arg0) { - T[] res = (T[])(new Object[this.size]); - for(int i=0;i{ - public boolean hasNext(); - public E next(); -} diff --git a/group12/247565311/week1/LinkedList.java b/group12/247565311/week1/LinkedList.java deleted file mode 100644 index 0b74925cbe..0000000000 --- a/group12/247565311/week1/LinkedList.java +++ /dev/null @@ -1,242 +0,0 @@ -package week1; - -import java.util.Collection; - -public class LinkedList implements List { - private Node head = null; - private Node tail = null; - private int size = 0; - - public LinkedList(){ - head = new Node(null); - tail = new Node(null); - head.next = tail; - tail.ahead = head; - size = 0; - } - public LinkedList(int arg0){ - head = new Node(null); - tail = new Node(null); - head.next = tail; - tail.ahead = head; - size = 0; - } - public Object clone(){ - LinkedList clone = null; - try { - clone = (LinkedList)(super.clone()); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } - clone.head = new Node(null); - clone.tail = new Node(null); - clone.size = 0; - for(Node x = head.next;x!=null;x = x.next){ - clone.add(x.val); - } - return clone; - } - @Override - public void add(Object val) { - Node n = new Node(val); - n.next = tail; - n.ahead = tail.ahead; - tail.ahead.next = n; - tail.ahead = n; - size += 1; - } - - @Override - public void add(int arg0, E arg1) { - if(arg0<0 || arg0>size) arg0=0; - Node n=new Node(arg1),p=head; - for(int i=0;i arg0) { - for(E o:arg0){ - this.add(o); - } - return true; - } - - public boolean addAll(int arg0, Collection arg1) { - for(E e:arg1){ - this.add(arg0,e); - arg0+=1; - } - return true; - } - - public void clear() { - head = new Node(null); - tail = new Node(null); - head.next = tail; - tail.ahead = head; - size = 0; - } - - public boolean contains(Object arg0) { - boolean flag = arg0==null; - Node n = head; - for(int i=0;i arg0) { - for(Object e:arg0){ - if(!this.contains(e)) return false; - } - return true; - } - - @Override - public E get(int arg0) { - E res = null; - if(arg0>-1 && arg0 < size){ - Node n = head; - for(int i=0;i iterator() { - - return null; - } - - public int lastIndexOf(Object arg0) { - boolean flag = arg0==null; - Node n = tail; - for(int i=size-1;i>-1;i--){ - n = n.ahead; - if(flag){ - if(n.val == null) return i; - }else{ - if(arg0.equals(n.val)) return i; - } - } - return -1; - } - - public boolean remove(Object arg0) { - Node n = head; - int index = this.indexOf(arg0); - if(index == -1) return false; - for(int i=0;isize-1) return null; - for(int i=0;i arg0) { - for(Object o:arg0){ - if(!this.remove(o)) return false; - } - return true; - } - - public boolean retainAll(Collection arg0) { - // ? - return false; - } - - public E set(int arg0, E arg1) { - if(arg0<0 || arg0>size-1) return null; - Node n=head; - for(int i=0;i T[] toArray(T[] arg0) { - T[]res = (T[]) new Object[size]; - Node n = head; - for(int i=0;i extends Iterator{ - public void add(Object o); - public void add(int index, E o); - public E get(int index); - public E remove(int index); - public int size(); -} diff --git a/group12/247565311/week1/Queue.java b/group12/247565311/week1/Queue.java deleted file mode 100644 index 78f25cb826..0000000000 --- a/group12/247565311/week1/Queue.java +++ /dev/null @@ -1,18 +0,0 @@ -package week1; -public class Queue { - private LinkedList data = new LinkedList(); - public void enQueue(E arg0){ - data.add(data.size(),arg0); - } - public E deQueue(){ - E res = data.get(0); - data.remove(0); - return res; - } - public int size(){ - return data.size(); - } - public boolean isEmpty(){ - return data.isEmpty(); - } -} diff --git a/group12/247565311/week1/Stack.java b/group12/247565311/week1/Stack.java deleted file mode 100644 index 5dcccc5fca..0000000000 --- a/group12/247565311/week1/Stack.java +++ /dev/null @@ -1,28 +0,0 @@ -package week1; - -import week1.List; - -public class Stack { - private ArrayList data = new ArrayList(); - public boolean isEmpty(){ - return data.isEmpty(); - } - public int size(){ - return data.size(); - } - public boolean push(E arg0){ - data.add(arg0); - return true; - } - public E pop(){ - if(this.isEmpty()) return null; - E res = data.get(data.size()-1); - data.remove(data.size()-1); - return res; - } - public E peek(){ - if(this.isEmpty()) return null; - E res = data.get(data.size()-1); - return res; - } -} diff --git a/group12/247565311/week2/ArrayUtil.java b/group12/247565311/week2/ArrayUtil.java deleted file mode 100644 index 00bab36625..0000000000 --- a/group12/247565311/week2/ArrayUtil.java +++ /dev/null @@ -1,206 +0,0 @@ -package week2; -import week1.ArrayList; - -public class ArrayUtil { - - /** - * ����һ����������a , �Ը������ֵ�����û� - ���磺 a = [7, 9 , 30, 3] , �û���Ϊ [3, 30, 9,7] - ��� a = [7, 9, 30, 3, 4] , �û���Ϊ [4,3, 30 , 9,7] - * @param origin - * @return - */ - public void reverseArray(int[] origin){ // time :O(n) - int leno = origin.length; - for(int i=0;i=len1){ - temparray[temp] = array2[p2]; - p2 += 1; - continue; - } - if(p2>=len2){ - temparray[temp] = array1[p1]; - p1 += 1; - continue; - } - if(array1[p1] > array2[p2]){ - temparray[temp] = array2[p2]; - p2 += 1; - }else{ - temparray[temp] = array1[p1]; - p1 += 1; - } - } - temp = 0; - for(int i=1;i data = new ArrayList(); - data.add(llast); - data.add(last); - while(last+llast li = new ArrayList(); - int cur = 2; - while(cur li = null,resli = new ArrayList(); - for(int i=6;i getAllElem(int arg0){ - ArrayList res = new ArrayList(); - for(int i=1;iparameters){ - if(actionName == null || parameters == null) return null; - List actions = null; - try { - File xmlfile = new File(System.getProperty("user.dir")+"\\bin\\week2\\struts.xml"); - Document doc = new SAXReader().read(xmlfile); - Element root = doc.getRootElement(); - actions = root.elements(); - } catch (DocumentException e) { - e.printStackTrace(); - } - - String className=""; - Element curActNode = null; - for(int i=0;i attrs = actions.get(i).attributes(); - for(int j=0;j class1 = null; - try { - class1 = Class.forName(className); - class1Instance = class1.newInstance(); - } catch (Exception e) { - e.printStackTrace(); - } - for(String key : parameters.keySet()){ - String methodName = "set"+(new StringBuilder()).append(Character.toUpperCase(key.charAt(0))).append(key.substring(1)).toString(); - Object methodPara=parameters.get(key); - try { - Method method =class1.getMethod(methodName, String.class); - method.invoke(class1Instance, methodPara); - } catch (Exception e) { - e.printStackTrace(); - } - } - Object exeResult = null; - try { - Method method =class1.getMethod("execute"); - exeResult = method.invoke(class1Instance); - } catch (Exception e) { - e.printStackTrace(); - } - - String jsp = null; - List results = curActNode.elements(); - for(int i=0;i attrs = results.get(i).attributes(); - for(int j=0;j para = new HashMap(); - view.setParameters(para); - - Field [] fields = class1.getDeclaredFields(); - for(int i=0;i params = new HashMap(); - params.put("name","test"); - params.put("password","1234"); - - - View view = Struts.runAction(actionName,params); - - Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); - Assert.assertEquals("login successful", view.getParameters().get("message")); - } - - @Test - public void testLoginActionFailed() { - String actionName = "login"; - Map params = new HashMap(); - params.put("name","test"); - params.put("password","123456"); //�����Ԥ��IJ�һ�� - - View view = Struts.runAction(actionName,params); - - Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); - Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); - } - -} diff --git a/group12/247565311/week2/View.java b/group12/247565311/week2/View.java deleted file mode 100644 index 4f88ad3b84..0000000000 --- a/group12/247565311/week2/View.java +++ /dev/null @@ -1,24 +0,0 @@ -package week2; -import java.util.Map; -public class View { - private String jsp; - @SuppressWarnings("rawtypes") - private Map parameters; - - public String getJsp(){ - return jsp; - } - public View setJsp(String jsp){ - this.jsp = jsp; - return this; - } - @SuppressWarnings("rawtypes") - public Map getParameters(){ - return parameters; - } - @SuppressWarnings("rawtypes") - public View setParameters(Map parameters){ - this.parameters = parameters; - return this; - } -} diff --git a/group12/247565311/week2/struts.xml b/group12/247565311/week2/struts.xml deleted file mode 100644 index 234232d0b6..0000000000 --- a/group12/247565311/week2/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - diff --git a/group12/247565311/week2_miniStruts/LoginAction.java b/group12/247565311/week2_miniStruts/LoginAction.java new file mode 100644 index 0000000000..f696180eeb --- /dev/null +++ b/group12/247565311/week2_miniStruts/LoginAction.java @@ -0,0 +1,30 @@ +package week2_miniStruts; + +public class LoginAction { + private String name ; + private String password; + private String message; + public String getName(){ + return name; + } + public String getPassword(){ + return password; + } + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + public void setName(String name){ + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group12/247565311/week2_miniStruts/Struts.java b/group12/247565311/week2_miniStruts/Struts.java new file mode 100644 index 0000000000..5ccadb610f --- /dev/null +++ b/group12/247565311/week2_miniStruts/Struts.java @@ -0,0 +1,101 @@ +package week2_miniStruts; +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.dom4j.Attribute; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +public class Struts { + @SuppressWarnings("unchecked") + public static View runAction(String actionName,Mapparameters){ + if(actionName == null || parameters == null) return null; + List actions = null; + try { + File xmlfile = new File(System.getProperty("user.dir")+"\\bin\\week2\\struts.xml"); + Document doc = new SAXReader().read(xmlfile); + Element root = doc.getRootElement(); + actions = root.elements(); + } catch (DocumentException e) { + e.printStackTrace(); + } + + String className=""; + Element curActNode = null; + for(int i=0;i attrs = actions.get(i).attributes(); + for(int j=0;j class1 = null; + try { + class1 = Class.forName(className); + class1Instance = class1.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + for(String key : parameters.keySet()){ + String methodName = "set"+(new StringBuilder()).append(Character.toUpperCase(key.charAt(0))).append(key.substring(1)).toString(); + Object methodPara=parameters.get(key); + try { + Method method =class1.getMethod(methodName, String.class); + method.invoke(class1Instance, methodPara); + } catch (Exception e) { + e.printStackTrace(); + } + } + Object exeResult = null; + try { + Method method =class1.getMethod("execute"); + exeResult = method.invoke(class1Instance); + } catch (Exception e) { + e.printStackTrace(); + } + + String jsp = null; + List results = curActNode.elements(); + for(int i=0;i attrs = results.get(i).attributes(); + for(int j=0;j para = new HashMap(); + view.setParameters(para); + + Field [] fields = class1.getDeclaredFields(); + for(int i=0;i params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //�����Ԥ��IJ�һ�� + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } + +} diff --git a/group12/247565311/week2_miniStruts/View.java b/group12/247565311/week2_miniStruts/View.java new file mode 100644 index 0000000000..3d69a03600 --- /dev/null +++ b/group12/247565311/week2_miniStruts/View.java @@ -0,0 +1,24 @@ +package week2_miniStruts; +import java.util.Map; +public class View { + private String jsp; + @SuppressWarnings("rawtypes") + private Map parameters; + + public String getJsp(){ + return jsp; + } + public View setJsp(String jsp){ + this.jsp = jsp; + return this; + } + @SuppressWarnings("rawtypes") + public Map getParameters(){ + return parameters; + } + @SuppressWarnings("rawtypes") + public View setParameters(Map parameters){ + this.parameters = parameters; + return this; + } +} diff --git a/group12/247565311/week3/DownloadThread.java b/group12/247565311/week3/DownloadThread.java deleted file mode 100644 index 2670bef00b..0000000000 --- a/group12/247565311/week3/DownloadThread.java +++ /dev/null @@ -1,61 +0,0 @@ -package week3; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.CyclicBarrier; - -import week3.api.Connection; - -public class DownloadThread extends Thread{ - Connection conn; - CyclicBarrier barrier; - int startPos; - int endPos; - String path = ""; - int step = 1024*200; // ÿ200kдһ���ļ� - public DownloadThread(CyclicBarrier _barrier, Connection conn, int startPos, int endPos,String filepath){ - this.conn = conn; - this.startPos = startPos; - this.endPos = endPos; - this.path = filepath; - this.barrier = _barrier; - } - public void run(){ - // ��ȡ���ص��ֽ����飬д���ļ���ע������һ�����̳߳��� - // �������ֻ��дһ���ֵ��ļ� - - // ��connect�����ȡ�ֽ����飬���û���ֽ������ˣ��ͱ�ʾ�ⲿ��������� - // ��filepathд�ļ� - if(conn == null) return; - int curEndPos = startPos; - while(curEndPos endPos) - curEndPos = endPos; - try { - byte[] data = conn.read(startPos, curEndPos); - RandomAccessFile files = new RandomAccessFile(path,"rw"); - files.seek(startPos); - files.write(data); - files.close(); - System.out.println("startPos"+startPos + ", length:"+data.length); - } catch (IOException e) { - e.printStackTrace(); - } - } - conn.close(); - try { - barrier.await(); - } catch (InterruptedException | BrokenBarrierException e) { - e.printStackTrace(); - } - } -} diff --git a/group12/247565311/week3/FileDownloader.java b/group12/247565311/week3/FileDownloader.java deleted file mode 100644 index 1a426c3682..0000000000 --- a/group12/247565311/week3/FileDownloader.java +++ /dev/null @@ -1,77 +0,0 @@ -package week3; -import java.util.concurrent.CyclicBarrier; -import java.io.IOException; -import java.io.RandomAccessFile; - -import week3.api.Connection; -import week3.api.ConnectionException; -import week3.api.ConnectionManager; -import week3.api.DownloadListener; -import week3.impl.ConnectionManagerImpl; - -public class FileDownloader { - private int MaxThreadNum = 4; - private String url = null,path=null; - DownloadListener listener = null; - private ConnectionManager cm = new ConnectionManagerImpl(); - - public FileDownloader(String weburl,String localpath) { - this.url = weburl; - this.path = localpath; - } - - public void execute() throws InterruptedException{ - // 在这里实现你的代码, 注意: 需要用多线程实现下载 - // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 - // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) - // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 - // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 - // 具体的实现思路: - // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 - // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 - // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 - // 3. 把byte数组写入到文件中 - // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 - - // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 - Connection conn = null; - CyclicBarrier barr= new CyclicBarrier(MaxThreadNum,new Runnable(){ - public void run(){ - listener.notifyFinished(); - } - }); - try { - conn = cm.open(this.url); - int length = conn.getContentLength(); - // 在这里创建出一个同样大小的空文件, 路径是path - RandomAccessFile tarfile = new RandomAccessFile(path,"rw"); - tarfile.setLength(length); - tarfile.close(); - Thread[] threads = new Thread[4]; - threads[0] = new DownloadThread(barr,cm.open(this.url),0,length/4,path); - threads[1] = new DownloadThread(barr,cm.open(this.url),length/4,length/2,path); - threads[2] = new DownloadThread(barr,cm.open(this.url),length/2,3*length/4,path); - threads[3] = new DownloadThread(barr,cm.open(this.url),3*length/4,length,path); - for(int i=0;i<4;i++) - threads[i].start(); - } catch (ConnectionException | IOException e) { - e.printStackTrace(); - }finally{ - if(conn != null){ - conn.close(); - } - } - } - public void setListener(DownloadListener listener) { - this.listener = listener; - } - public void setConnectionManager(ConnectionManager ucm){ - this.cm = ucm; - } - public DownloadListener getListener(){ - return this.listener; - } - public double getDownPercent(){ - return 0.0; - } -} diff --git a/group12/247565311/week3/FileDownloaderTest.java b/group12/247565311/week3/FileDownloaderTest.java deleted file mode 100644 index 3c729218d3..0000000000 --- a/group12/247565311/week3/FileDownloaderTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package week3; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import week3.api.ConnectionManager; -import week3.api.DownloadListener; -import week3.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://music.163.com/api/pc/download/latest"; - String path = "D:\\hellp.exe"; - FileDownloader downloader = new FileDownloader(url,path); - ConnectionManager cm = new ConnectionManagerImpl(); - downloader.setConnectionManager(cm); - downloader.setListener(new DownloadListener() { - @Override - public void notifyFinished() { - downloadFinished = true; - } - }); - double time = 0; - try { - downloader.execute(); - } catch (InterruptedException e1) { - e1.printStackTrace(); - } - while (!downloadFinished) { - try { - Thread.sleep(100);//休眠0.1秒 - - time += 1; - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - System.out.println("下载完成!耗时:"+time/10.0+" 秒。"); - } -} diff --git a/group12/247565311/week3/LinkedList.java b/group12/247565311/week3/LinkedList.java deleted file mode 100644 index dbf9465386..0000000000 --- a/group12/247565311/week3/LinkedList.java +++ /dev/null @@ -1,252 +0,0 @@ -package week3; - - -import java.util.NoSuchElementException; - -import week1.Iterator; -import week1.List; - -public class LinkedList implements List { - private Node head = new Node(); - private int size = 0; - private void checkAddIndex(int index){ - if(index > size || index<0) throw new IndexOutOfBoundsException("Index:"+index+", Size:"+size); - } - private void checkGetIndex(int index){ - if(index >= size || index<0) throw new IndexOutOfBoundsException("Index:"+index+", Size:"+size); - } - public void add(Object o){ - Node newNode = new Node(o),p = head; - while(p.next!=null) - p = p.next; - p.next = newNode; - size += 1; - } - /** - * - * */ - public void add(int index , Object o){ - checkAddIndex(index); - Node p = head; - for(int i=0;i7->10 , ���ú��Ϊ 10->7->3 - */ - public void reverse(){ - Node rhead = new Node(),p=head; - for(int i=0;i5->7->8 , ɾ���Ժ��ֵΪ 7->8 - * ���list = 2->5->7->8->10 ,ɾ���Ժ��ֵΪ7,8,10 - - */ - public void removeFirstHalf(){ - int numToRemove = size/2; - for(int i=0;i101->201->301->401->501->601->701 - * listB = 1->3->4->6 - * ���صĽ��Ӧ����[101,301,401,601] - * @param list - */ - public int[] getElements(LinkedList list){ - int []res = new int[list.size()]; - Node p = head.next,q = list.head.next; - int lenl = list.size(),index=0; - for(int i=0;imax) return; // Ŀ������ (min,max) - Node p = head; - while(p.next != null && ((Integer)p.next.data).intValue()<=min) // ��������ɵ�Ԫ�� - p = p.next; - while(p.next != null && ((Integer)p.next.data).intValue()0)output.write(res,0,len); - else break; - } - return Arrays.copyOf(output.toByteArray(), endPos-startPos); - } - } catch (IOException e) { - e.printStackTrace(); - } - if(conn!=null) conn.disconnect(); - return res; - } - - @Override - public int getContentLength() { - try{ - URLConnection con = url.openConnection(); - return con.getContentLength(); - }catch(Exception e){ - e.printStackTrace(); - } - return -1; - } - - @Override - public void close() { - } -} diff --git a/group12/247565311/week3/impl/ConnectionManagerImpl.java b/group12/247565311/week3/impl/ConnectionManagerImpl.java deleted file mode 100644 index b4a7cf381f..0000000000 --- a/group12/247565311/week3/impl/ConnectionManagerImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package week3.impl; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; - -import week3.api.Connection; -import week3.api.ConnectionException; -import week3.api.ConnectionManager; - -public class ConnectionManagerImpl implements ConnectionManager { - URL urllink = null; - ConnectionImpl conImpl = null; - @Override - public Connection open(String url) throws ConnectionException { - return new ConnectionImpl(url); - } -} diff --git a/group12/247565311/week3_fileDownloader/DownloadThread.java b/group12/247565311/week3_fileDownloader/DownloadThread.java new file mode 100644 index 0000000000..11d228b652 --- /dev/null +++ b/group12/247565311/week3_fileDownloader/DownloadThread.java @@ -0,0 +1,55 @@ +package week3_fileDownloader; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +import week3_fileDownloader.api.Connection; + +public class DownloadThread extends Thread{ + Connection conn; + CyclicBarrier barrier; + int startPos; + int endPos; + String path = ""; + int step = 1024*200; // ÿ200kдһ���ļ� + public DownloadThread(CyclicBarrier _barrier, Connection conn, int startPos, int endPos,String filepath){ + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.path = filepath; + this.barrier = _barrier; + } + public void run(){ + // ��ȡ���ص��ֽ����飬д���ļ���ע������һ�����̳߳��� + // �������ֻ��дһ���ֵ��ļ� + + // ��connect�����ȡ�ֽ����飬���û���ֽ������ˣ��ͱ�ʾ�ⲿ��������� + // ��filepathд�ļ� + if(conn == null) return; + int curEndPos = startPos; + while(curEndPos endPos) + curEndPos = endPos; + try { + byte[] data = conn.read(startPos, curEndPos); + RandomAccessFile files = new RandomAccessFile(path,"rw"); + files.seek(startPos); + files.write(data); + files.close(); + System.out.println("startPos"+startPos + ", length:"+data.length); + } catch (IOException e) { + e.printStackTrace(); + } + } + conn.close(); + try { + barrier.await(); + } catch (InterruptedException | BrokenBarrierException e) { + e.printStackTrace(); + } + } +} diff --git a/group12/247565311/week3_fileDownloader/FileDownloader.java b/group12/247565311/week3_fileDownloader/FileDownloader.java new file mode 100644 index 0000000000..2c23ac39c0 --- /dev/null +++ b/group12/247565311/week3_fileDownloader/FileDownloader.java @@ -0,0 +1,78 @@ +package week3_fileDownloader; + +import java.util.concurrent.CyclicBarrier; +import java.io.IOException; +import java.io.RandomAccessFile; + +import week3_fileDownloader.api.Connection; +import week3_fileDownloader.api.ConnectionException; +import week3_fileDownloader.api.ConnectionManager; +import week3_fileDownloader.api.DownloadListener; +import week3_fileDownloader.impl.ConnectionManagerImpl; + +public class FileDownloader { + private int MaxThreadNum = 4; + private String url = null,path=null; + DownloadListener listener = null; + private ConnectionManager cm = new ConnectionManagerImpl(); + + public FileDownloader(String weburl,String localpath) { + this.url = weburl; + this.path = localpath; + } + + public void execute() throws InterruptedException{ + // 鍦ㄨ繖閲屽疄鐜颁綘鐨勪唬鐮侊紝 娉ㄦ剰锛�闇�鐢ㄥ绾跨▼瀹炵幇涓嬭浇 + // 杩欎釜绫讳緷璧栦簬鍏朵粬鍑犱釜鎺ュ彛, 浣犻渶瑕佸啓杩欏嚑涓帴鍙g殑瀹炵幇浠g爜 + // (1) ConnectionManager , 鍙互鎵撳紑涓�釜杩炴帴锛岄�杩嘋onnection鍙互璇诲彇鍏朵腑鐨勪竴娈碉紙鐢╯tartPos, endPos鏉ユ寚瀹氾級 + // (2) DownloadListener, 鐢变簬鏄绾跨▼涓嬭浇锛�璋冪敤杩欎釜绫荤殑瀹㈡埛绔笉鐭ラ亾浠�箞鏃跺�缁撴潫锛屾墍浠ヤ綘闇�瀹炵幇褰撴墍鏈� + // 绾跨▼閮芥墽琛屽畬浠ュ悗锛�璋冪敤listener鐨刵otifiedFinished鏂规硶锛�杩欐牱瀹㈡埛绔氨鑳芥敹鍒伴�鐭ャ� + // 鍏蜂綋鐨勫疄鐜版�璺細 + // 1. 闇�璋冪敤ConnectionManager鐨刼pen鏂规硶鎵撳紑杩炴帴锛�鐒跺悗閫氳繃Connection.getContentLength鏂规硶鑾峰緱鏂囦欢鐨勯暱搴� + // 2. 鑷冲皯鍚姩3涓嚎绋嬩笅杞斤紝 娉ㄦ剰姣忎釜绾跨▼闇�鍏堣皟鐢–onnectionManager鐨刼pen鏂规硶 + // 鐒跺悗璋冪敤read鏂规硶锛�read鏂规硶涓湁璇诲彇鏂囦欢鐨勫紑濮嬩綅缃拰缁撴潫浣嶇疆鐨勫弬鏁帮紝 杩斿洖鍊兼槸byte[]鏁扮粍 + // 3. 鎶奲yte鏁扮粍鍐欏叆鍒版枃浠朵腑 + // 4. 鎵�湁鐨勭嚎绋嬮兘涓嬭浇瀹屾垚浠ュ悗锛�闇�璋冪敤listener鐨刵otifiedFinished鏂规硶 + + // 涓嬮潰鐨勪唬鐮佹槸绀轰緥浠g爜锛�涔熷氨鏄鍙湁涓�釜绾跨▼锛�浣犻渶瑕佹敼閫犳垚澶氱嚎绋嬬殑銆� + Connection conn = null; + CyclicBarrier barr= new CyclicBarrier(MaxThreadNum,new Runnable(){ + public void run(){ + listener.notifyFinished(); + } + }); + try { + conn = cm.open(this.url); + int length = conn.getContentLength(); + // 鍦ㄨ繖閲屽垱寤哄嚭涓�釜鍚屾牱澶у皬鐨勭┖鏂囦欢锛�璺緞鏄痯ath + RandomAccessFile tarfile = new RandomAccessFile(path,"rw"); + tarfile.setLength(length); + tarfile.close(); + Thread[] threads = new Thread[4]; + threads[0] = new DownloadThread(barr,cm.open(this.url),0,length/4,path); + threads[1] = new DownloadThread(barr,cm.open(this.url),length/4,length/2,path); + threads[2] = new DownloadThread(barr,cm.open(this.url),length/2,3*length/4,path); + threads[3] = new DownloadThread(barr,cm.open(this.url),3*length/4,length,path); + for(int i=0;i<4;i++) + threads[i].start(); + } catch (ConnectionException | IOException e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + } + public void setListener(DownloadListener listener) { + this.listener = listener; + } + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + public DownloadListener getListener(){ + return this.listener; + } + public double getDownPercent(){ + return 0.0; + } +} diff --git a/group12/247565311/week3_fileDownloader/FileDownloaderTest.java b/group12/247565311/week3_fileDownloader/FileDownloaderTest.java new file mode 100644 index 0000000000..3488fd5245 --- /dev/null +++ b/group12/247565311/week3_fileDownloader/FileDownloaderTest.java @@ -0,0 +1,50 @@ +package week3_fileDownloader; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import week3_fileDownloader.api.ConnectionManager; +import week3_fileDownloader.api.DownloadListener; +import week3_fileDownloader.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://music.163.com/api/pc/download/latest"; + String path = "D:\\hellp.exe"; + FileDownloader downloader = new FileDownloader(url,path); + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + }); + double time = 0; + try { + downloader.execute(); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + while (!downloadFinished) { + try { + Thread.sleep(100);//浼戠湢0.1绉� + + time += 1; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("涓嬭浇瀹屾垚锛佽�鏃讹細"+time/10.0+" 绉掋�"); + } +} diff --git a/group12/247565311/week3_fileDownloader/api/Connection.java b/group12/247565311/week3_fileDownloader/api/Connection.java new file mode 100644 index 0000000000..5100870e1f --- /dev/null +++ b/group12/247565311/week3_fileDownloader/api/Connection.java @@ -0,0 +1,23 @@ +package week3_fileDownloader.api; + +import java.io.IOException; +import java.net.HttpURLConnection; + +public interface Connection{ + /** + * 缁欏畾寮�鍜岀粨鏉熶綅缃紝 璇诲彇鏁版嵁锛�杩斿洖鍊兼槸瀛楄妭鏁扮粍 + * @param startPos 寮�浣嶇疆锛�浠�寮� + * @param endPos 缁撴潫浣嶇疆 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 寰楀埌鏁版嵁鍐呭鐨勯暱搴� * @return + */ + public int getContentLength(); + + /** + * 鍏抽棴杩炴帴 + */ + public void close(); +} diff --git a/group12/247565311/week3_fileDownloader/api/ConnectionException.java b/group12/247565311/week3_fileDownloader/api/ConnectionException.java new file mode 100644 index 0000000000..4a9cfd8aa6 --- /dev/null +++ b/group12/247565311/week3_fileDownloader/api/ConnectionException.java @@ -0,0 +1,5 @@ +package week3_fileDownloader.api; + +public class ConnectionException extends Exception { + private String exceptionstr = ""; +} diff --git a/group12/247565311/week3_fileDownloader/api/ConnectionManager.java b/group12/247565311/week3_fileDownloader/api/ConnectionManager.java new file mode 100644 index 0000000000..f917cde2e9 --- /dev/null +++ b/group12/247565311/week3_fileDownloader/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package week3_fileDownloader.api; + +public interface ConnectionManager { + /** + * 缁欏畾涓�釜url , 鎵撳紑涓�釜杩炴帴 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group12/247565311/week3_fileDownloader/api/DownloadListener.java b/group12/247565311/week3_fileDownloader/api/DownloadListener.java new file mode 100644 index 0000000000..27fc35452f --- /dev/null +++ b/group12/247565311/week3_fileDownloader/api/DownloadListener.java @@ -0,0 +1,5 @@ +package week3_fileDownloader.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group12/247565311/week3_fileDownloader/impl/ConnectionImpl.java b/group12/247565311/week3_fileDownloader/impl/ConnectionImpl.java new file mode 100644 index 0000000000..78f393e07e --- /dev/null +++ b/group12/247565311/week3_fileDownloader/impl/ConnectionImpl.java @@ -0,0 +1,65 @@ +package week3_fileDownloader.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; + +import week3_fileDownloader.api.Connection; + +public class ConnectionImpl implements Connection{ + URL url = null; + public ConnectionImpl(String str){ + try { + url = new URL(str); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + // ��������Ҫ������ִ�����أ���ȡ�ֽ����� + // ����ฺ��򿪡��ر��������� + @Override + public byte[] read(int startPos, int endPos) { + HttpURLConnection conn = null; + byte[]res = null; + try { + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestProperty("Range","bytes="+startPos+"-"+endPos); + int responcode = conn.getResponseCode(); + if(200 < responcode && responcode < 300){ + InputStream input = conn.getInputStream(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + res = new byte[2048]; + while(output.size()0)output.write(res,0,len); + else break; + } + return Arrays.copyOf(output.toByteArray(), endPos-startPos); + } + } catch (IOException e) { + e.printStackTrace(); + } + if(conn!=null) conn.disconnect(); + return res; + } + + @Override + public int getContentLength() { + try{ + URLConnection con = url.openConnection(); + return con.getContentLength(); + }catch(Exception e){ + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + } +} diff --git a/group12/247565311/week3_fileDownloader/impl/ConnectionManagerImpl.java b/group12/247565311/week3_fileDownloader/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..7aab7eb651 --- /dev/null +++ b/group12/247565311/week3_fileDownloader/impl/ConnectionManagerImpl.java @@ -0,0 +1,18 @@ +package week3_fileDownloader.impl; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +import week3_fileDownloader.api.Connection; +import week3_fileDownloader.api.ConnectionException; +import week3_fileDownloader.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + URL urllink = null; + ConnectionImpl conImpl = null; + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } +} diff --git a/group12/247565311/week5/ClassFileLoader.java b/group12/247565311/week5/ClassFileLoader.java deleted file mode 100644 index fc5e920f19..0000000000 --- a/group12/247565311/week5/ClassFileLoader.java +++ /dev/null @@ -1,63 +0,0 @@ -package week5; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -public class ClassFileLoader { - private List clzPaths = new ArrayList(); - - public byte[] readBinaryCode(String className) throws Exception { - for(String s:clzPaths){ - String filename = s+className+".class"; - File file = new File(filename); - if(file.exists())return loadClassFile(filename); - } - return null; - } - - private byte[] loadClassFile(String clzFileName) throws Exception { - File file = new File(clzFileName); - long filelength = file.length(); - byte[]res = null; - if(filelength>Integer.MAX_VALUE)throw new IOException("�ļ�����"); - try { - FileInputStream fileinput = new FileInputStream(file); - res = new byte[(int) filelength]; - int offset=0,length=0; - while(offset-1)) - offset += length; - fileinput.close(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return res; - } - - public void addClassPath(String path) { - clzPaths.add(path); - } - - public String getClassPath_V1(){ - String res = ""; - int size = clzPaths.size(); - for(int i=0;i lib = new HashSet(); - class Node{ - int val; - Node next; - public Node(int _val){ - val = _val; - next = null; - } - } - public LRU(int _size){ - if(_size>0) { - this.size = _size; - } - } - public int[] getAll(){ - int length = lib.size(),index = 0; - int []res = new int[length]; - Node p = head.next; - while(p!=null){ - res[index] = p.val; - index += 1; - p = p.next; - } - return res; - } - public void add(int e){ - int index = 0; - if(lib.contains(e)){ - Node p = head; - while(p.next!= null){ - if(p.next.val == e){ - Node newn = p.next; - p.next = newn.next; - newn.next = head.next; - head.next = newn; - break; - } - p = p.next; - } - }else{ - if(lib.size() == size){ - lib.add(e); - Node newn = new Node(e); - newn.next = head.next; - head.next = newn; - Node p = head; - while(p.next.next != null) - p = p.next; - Node deln = p.next; - lib.remove(deln.val); - p.next = null; - }else{ - Node newn = new Node(e); - newn.next = head.next; - head.next = newn; - lib.add(e); - } - } - } -} diff --git a/group12/247565311/week5/LRUTest.java b/group12/247565311/week5/LRUTest.java deleted file mode 100644 index 0ee0d95309..0000000000 --- a/group12/247565311/week5/LRUTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package week5; - -import static org.junit.Assert.*; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class LRUTest { - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testAdd() { - LRU lru = new LRU(5); - lru.add(3); - lru.add(7); - lru.add(5); - lru.add(8); - lru.add(10); - Assert.assertArrayEquals(new int[]{10,8,5,7,3}, lru.getAll()); - lru.add(5); - lru.add(3); - Assert.assertArrayEquals(new int[]{3,5,10,8,7}, lru.getAll()); - lru.add(8); - lru.add(11); - Assert.assertArrayEquals(new int[]{11,8,3,5,10}, lru.getAll()); - } -} diff --git a/group12/247565311/week567_miniJVM/attr/AttributeInfo.java b/group12/247565311/week567_miniJVM/attr/AttributeInfo.java new file mode 100644 index 0000000000..e97ebe0065 --- /dev/null +++ b/group12/247565311/week567_miniJVM/attr/AttributeInfo.java @@ -0,0 +1,24 @@ +package week567_miniJVM.attr; + + + + +public abstract class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + int attrNameIndex; + int attrLen ; + public AttributeInfo(int attrNameIndex, int attrLen) { + + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } + + +} + + diff --git a/group12/247565311/week567_miniJVM/attr/CodeAttr.java b/group12/247565311/week567_miniJVM/attr/CodeAttr.java new file mode 100644 index 0000000000..b32d6aada9 --- /dev/null +++ b/group12/247565311/week567_miniJVM/attr/CodeAttr.java @@ -0,0 +1,63 @@ + + + +package week567_miniJVM.attr; + +import week567_miniJVM.clz.ClassFile; +import week567_miniJVM.constant.ConstantPool; +import week567_miniJVM.loader.ByteCodeIterator; + + +public class CodeAttr extends AttributeInfo { + private int maxStack ; + private int maxLocals ; + private int codeLen ; + private String code; + public String getCode() { + return code; + } + + //private ByteCodeCommand[] cmds ; + //public ByteCodeCommand[] getCmds() { + // return cmds; + //} + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + //this.cmds = cmds; + } + + public void setLineNumberTable(LineNumberTable t) { + this.lineNumTable = t; + } + + public void setLocalVariableTable(LocalVariableTable t) { + this.localVarTable = t; + } + + public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ + + + return null; + } + private void setStackMapTable(StackMapTable t) { + this.stackMapTable = t; + + } + + + + + +} + + + + diff --git a/group12/247565311/week567_miniJVM/attr/LineNumberTable.java b/group12/247565311/week567_miniJVM/attr/LineNumberTable.java new file mode 100644 index 0000000000..1160f1b274 --- /dev/null +++ b/group12/247565311/week567_miniJVM/attr/LineNumberTable.java @@ -0,0 +1,51 @@ + +package week567_miniJVM.attr; + +import java.util.ArrayList; +import java.util.List; + +import week567_miniJVM.loader.ByteCodeIterator; + +public class LineNumberTable extends AttributeInfo { + List items = new ArrayList(); + + private static class LineNumberItem{ + int startPC; + int lineNum; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + public void addLineNumberItem(LineNumberItem item){ + this.items.add(item); + } + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + + } + + public static LineNumberTable parse(ByteCodeIterator iter){ + + return null; + } + + + +} + + + + + + + + diff --git a/group12/247565311/week567_miniJVM/attr/LocalVariableItem.java b/group12/247565311/week567_miniJVM/attr/LocalVariableItem.java new file mode 100644 index 0000000000..5ce8ad8810 --- /dev/null +++ b/group12/247565311/week567_miniJVM/attr/LocalVariableItem.java @@ -0,0 +1,47 @@ + +package week567_miniJVM.attr; + +public class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getNameIndex() { + return nameIndex; + } + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + public int getDescIndex() { + return descIndex; + } + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } +} + + + + + + + diff --git a/group12/247565311/week567_miniJVM/attr/LocalVariableTable.java b/group12/247565311/week567_miniJVM/attr/LocalVariableTable.java new file mode 100644 index 0000000000..c8dbf11b70 --- /dev/null +++ b/group12/247565311/week567_miniJVM/attr/LocalVariableTable.java @@ -0,0 +1,37 @@ + + +package week567_miniJVM.attr; + + +import java.util.ArrayList; +import java.util.List; + +import week567_miniJVM.constant.ConstantPool; + +import week567_miniJVM.loader.ByteCodeIterator; + +public class LocalVariableTable extends AttributeInfo{ + + List items = new ArrayList(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LocalVariableTable parse(ByteCodeIterator iter){ + + return null; + } + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + + +} + + + + + + + diff --git a/group12/247565311/week567_miniJVM/attr/StackMapTable.java b/group12/247565311/week567_miniJVM/attr/StackMapTable.java new file mode 100644 index 0000000000..c6b72f2655 --- /dev/null +++ b/group12/247565311/week567_miniJVM/attr/StackMapTable.java @@ -0,0 +1,44 @@ + +package week567_miniJVM.attr; + + +import week567_miniJVM.loader.ByteCodeIterator; + +public class StackMapTable extends AttributeInfo{ + + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.nextU2ToInt(); + int len = iter.nextU4ToInt(); + StackMapTable t = new StackMapTable(index,len); + + //鍚庨潰鐨凷tackMapTable澶繃澶嶆潅锛�涓嶅啀澶勭悊锛�鍙妸鍘熷鐨勪唬鐮佽杩涙潵淇濆瓨 + String code = iter.nextUxToHexString(len); + t.setOriginalCode(code); + + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} + + + + + + + + + + + + + diff --git a/group12/247565311/week567_miniJVM/clz/AccessFlag.java b/group12/247565311/week567_miniJVM/clz/AccessFlag.java new file mode 100644 index 0000000000..cb28fbe259 --- /dev/null +++ b/group12/247565311/week567_miniJVM/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package week567_miniJVM.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group12/247565311/week567_miniJVM/clz/ClassFile.java b/group12/247565311/week567_miniJVM/clz/ClassFile.java new file mode 100644 index 0000000000..91226364b8 --- /dev/null +++ b/group12/247565311/week567_miniJVM/clz/ClassFile.java @@ -0,0 +1,84 @@ +package week567_miniJVM.clz; + +import week567_miniJVM.constant.ClassInfo; +import week567_miniJVM.constant.ConstantPool; +import week567_miniJVM.field.Field; +import week567_miniJVM.method.Method; +import structure.week1.ArrayList; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + + System.out.println("Super Class Name:"+ getSuperClassName()); + + + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } + public ArrayList getMethods() { + return null; + } + public ArrayList getFields() { + return null; + } +} diff --git a/group12/247565311/week567_miniJVM/clz/ClassIndex.java b/group12/247565311/week567_miniJVM/clz/ClassIndex.java new file mode 100644 index 0000000000..77118cafa6 --- /dev/null +++ b/group12/247565311/week567_miniJVM/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package week567_miniJVM.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group12/247565311/week567_miniJVM/constant/ClassInfo.java b/group12/247565311/week567_miniJVM/constant/ClassInfo.java new file mode 100644 index 0000000000..77aa730b16 --- /dev/null +++ b/group12/247565311/week567_miniJVM/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package week567_miniJVM.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index ; + public ClassInfo(ConstantPool pool) { + super(pool); + } + public int getUtf8Index() { + return utf8Index; + } + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group12/247565311/week567_miniJVM/constant/ConstantInfo.java b/group12/247565311/week567_miniJVM/constant/ConstantInfo.java new file mode 100644 index 0000000000..7277bd18c4 --- /dev/null +++ b/group12/247565311/week567_miniJVM/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package week567_miniJVM.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group12/247565311/week567_miniJVM/constant/ConstantPool.java b/group12/247565311/week567_miniJVM/constant/ConstantPool.java new file mode 100644 index 0000000000..fb35f6c253 --- /dev/null +++ b/group12/247565311/week567_miniJVM/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package week567_miniJVM.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group12/247565311/week567_miniJVM/constant/FieldRefInfo.java b/group12/247565311/week567_miniJVM/constant/FieldRefInfo.java new file mode 100644 index 0000000000..20e7d91e67 --- /dev/null +++ b/group12/247565311/week567_miniJVM/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package week567_miniJVM.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group12/247565311/week567_miniJVM/constant/MethodRefInfo.java b/group12/247565311/week567_miniJVM/constant/MethodRefInfo.java new file mode 100644 index 0000000000..82b29c7446 --- /dev/null +++ b/group12/247565311/week567_miniJVM/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package week567_miniJVM.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group12/247565311/week567_miniJVM/constant/NameAndTypeInfo.java b/group12/247565311/week567_miniJVM/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..3a87554806 --- /dev/null +++ b/group12/247565311/week567_miniJVM/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package week567_miniJVM.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group12/247565311/week567_miniJVM/constant/NullConstantInfo.java b/group12/247565311/week567_miniJVM/constant/NullConstantInfo.java new file mode 100644 index 0000000000..1b9ed25aba --- /dev/null +++ b/group12/247565311/week567_miniJVM/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package week567_miniJVM.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group12/247565311/week567_miniJVM/constant/StringInfo.java b/group12/247565311/week567_miniJVM/constant/StringInfo.java new file mode 100644 index 0000000000..7a8e8da135 --- /dev/null +++ b/group12/247565311/week567_miniJVM/constant/StringInfo.java @@ -0,0 +1,26 @@ +package week567_miniJVM.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index; + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group12/247565311/week567_miniJVM/constant/UTF8Info.java b/group12/247565311/week567_miniJVM/constant/UTF8Info.java new file mode 100644 index 0000000000..ac2341bda9 --- /dev/null +++ b/group12/247565311/week567_miniJVM/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package week567_miniJVM.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group12/247565311/week567_miniJVM/field/Field.java b/group12/247565311/week567_miniJVM/field/Field.java new file mode 100644 index 0000000000..47eac5a308 --- /dev/null +++ b/group12/247565311/week567_miniJVM/field/Field.java @@ -0,0 +1,33 @@ +package week567_miniJVM.field; + +import week567_miniJVM.constant.ConstantPool; +import week567_miniJVM.constant.UTF8Info; +import week567_miniJVM.loader.ByteCodeIterator; + + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + + + private ConstantPool pool; + + public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + + + public static Field parse(ConstantPool pool,ByteCodeIterator iter){ + + return null; + } + +} \ No newline at end of file diff --git a/group12/247565311/week567_miniJVM/loader/ByteCodeIterator.java b/group12/247565311/week567_miniJVM/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..d38345b3fe --- /dev/null +++ b/group12/247565311/week567_miniJVM/loader/ByteCodeIterator.java @@ -0,0 +1,20 @@ +package week567_miniJVM.loader; + +public class ByteCodeIterator { + + public int nextU2ToInt() { + // TODO �Զ����ɵķ������ + return 0; + } + + public int nextU4ToInt() { + // TODO �Զ����ɵķ������ + return 0; + } + + public String nextUxToHexString(int len) { + // TODO �Զ����ɵķ������ + return null; + } + +} diff --git a/group12/247565311/week567_miniJVM/loader/ClassFileLoader.java b/group12/247565311/week567_miniJVM/loader/ClassFileLoader.java new file mode 100644 index 0000000000..89c66a8197 --- /dev/null +++ b/group12/247565311/week567_miniJVM/loader/ClassFileLoader.java @@ -0,0 +1,59 @@ +package week567_miniJVM.loader; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import week567_miniJVM.clz.ClassFile; + +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws Exception { + for(String s:clzPaths){ + String filename = s+className+".class"; + File file = new File(filename); + if(file.exists())return loadClassFile(filename); + } + return null; + } + public ClassFile loadClass(String className){ + return null; + } + private byte[] loadClassFile(String clzFileName) throws Exception { + File file = new File(clzFileName); + long filelength = file.length(); + byte[]res = null; + if(filelength>Integer.MAX_VALUE)throw new IOException("�ļ�����"); + try { + FileInputStream fileinput = new FileInputStream(file); + res = new byte[(int) filelength]; + int offset=0,length=0; + while(offset-1)) + offset += length; + fileinput.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return res; + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + public String getClassPath(){ + String res = ""; + int size = clzPaths.size(); + for(int i=0;i", utf8Info.getValue()); + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + // 随机抽查一个 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + /** + * miniJVM第三次作业测试用例 + */ + @Test + public void testReadFields(){ + ArrayList fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + @Test + public void testMethods(){ + ArrayList methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } +} \ No newline at end of file diff --git a/group12/247565311/week567_miniJVM/test/EmployeeV1.java b/group12/247565311/week567_miniJVM/test/EmployeeV1.java new file mode 100644 index 0000000000..b9855461ae --- /dev/null +++ b/group12/247565311/week567_miniJVM/test/EmployeeV1.java @@ -0,0 +1,5 @@ +package week567_miniJVM.test; + +public class EmployeeV1 { + +} diff --git a/group12/247565311/week567_miniJVM/util/Util.java b/group12/247565311/week567_miniJVM/util/Util.java new file mode 100644 index 0000000000..c10eaee6f2 --- /dev/null +++ b/group12/247565311/week567_miniJVM/util/Util.java @@ -0,0 +1,24 @@ +package week567_miniJVM.util; + +public class Util { + public static int byteToInt(byte[] codes){ + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i - - - - - - - - + + + + + + + + diff --git a/group12/382266293/coding/basic/collection/concrete/ArrayList.java b/group12/382266293/coding/basic/collection/concrete/ArrayList.java index 3eeca56fee..71accca366 100644 --- a/group12/382266293/coding/basic/collection/concrete/ArrayList.java +++ b/group12/382266293/coding/basic/collection/concrete/ArrayList.java @@ -70,6 +70,7 @@ public void addLast(E e) { } public E removeLast() { + checkIndex(size); return elements[--size]; } diff --git a/group12/382266293/coding/basic/linklist/LRUPageFrame.java b/group12/382266293/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..31b22dc26b --- /dev/null +++ b/group12/382266293/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,163 @@ +package linklist; + +/** + * 用双向链表实现LRU算法 + * + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node(int pageNum) { + this.pageNum = pageNum; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + pageNum; + return result; + } + + @Override + public String toString() { + return "Node [pageNum=" + pageNum + "]"; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Node other = (Node) obj; + if (pageNum != other.pageNum) + return false; + return true; + } + + } + + private int capacity; + + private Node first;// 链表头 + private Node last;// 链表尾 + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + + } + + private int size; + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + if (size < this.capacity) { + addNode(pageNum); + return; + } + + Node p = findNode(pageNum); + if (null == p) { + p = new Node(pageNum); + p.next = first; + first.prev = p; + first = p; + moveLastPoint(); + return; + } + + if (p == first) { + return; + } + + if (p == last) { + p.next = first; + first.prev = p; + first = p; + moveLastPoint(); + return; + } + + movePtoFirst(p); + + } + + private void moveLastPoint() { + last = last.prev; + last.next = null; + } + + private void movePtoFirst(Node p) { + p.prev.next = p.next; + p.next.prev = p.prev; + first.prev = p; + p.next = first; + first = p; + } + + private void addNode(int pageNum) { + Node node = new Node(pageNum); + if (null == first) { + first = node; + size++; + return; + } + + node.next = first; + first.prev = node; + first = node; + size++; + + if (null == last) { + last = node.next; + return; + } + + } + + private Node findNode(int pageNum) { + Node node = first; + while (null != node) { + if (node.pageNum != pageNum) { + node = node.next; + } else { + return node; + } + } + return null; + } + + public static void main(String[] args) { + + } + + public String toString() { + StringBuilder buffer = new StringBuilder(); + Node node = first; + while (node != null) { + buffer.append(node.pageNum); + + node = node.next; + if (node != null) { + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group12/382266293/coding/basic/linklist/LRUPageFrameTest.java b/group12/382266293/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..7745d31569 --- /dev/null +++ b/group12/382266293/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,32 @@ +package linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(4); + frame.access(7); + frame.access(0); + frame.access(1); + frame.access(9); + Assert.assertEquals("9,1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,9,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,9,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,9,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2,9", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2,9", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3,2", frame.toString()); + } + +} diff --git a/group12/382266293/coding/basic/stack/StackUtil.java b/group12/382266293/coding/basic/stack/StackUtil.java new file mode 100644 index 0000000000..706bcd7033 --- /dev/null +++ b/group12/382266293/coding/basic/stack/StackUtil.java @@ -0,0 +1,140 @@ +package stack; + +import static org.junit.Assert.assertEquals; + +import java.util.Objects; +import java.util.Stack; + +public class StackUtil { + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack stack) { + if (stack.isEmpty()) { + return; + } + int i = getAndRemoveLastElement(stack); + reverse(stack); + stack.push(i); + } + + public static int getAndRemoveLastElement(Stack stack) { + int result = stack.pop(); + if (stack.isEmpty()) { + return result; + } else { + int last = getAndRemoveLastElement(stack); + stack.push(result); + return last; + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s, Object o) { + if (s.isEmpty()) { + return; + } + Stack s2 = new Stack(); + while (s.peek() != null) { + if (!Objects.equals(o, s.peek())) { + s2.push(s.pop()); + } else { + s.pop(); + break; + } + } + while (!s2.isEmpty()) { + s.push(s2.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, + * 可以使用另外一个栈来辅助 + * + * @param len + * @return + */ + public static Object[] getTop(Stack s, int len) { + if (s.isEmpty()) { + return new Object[0]; + } + + int len1 = (s.size() < len) ? s.size() : len; + + Object[] result = new Object[len1]; + Stack s2 = new Stack(); + Object o = null; + for (int i = 0; i < len1; i++) { + o = s.pop(); + result[i] = o; + s2.push(o); + } + while (!s2.isEmpty()) { + s.push(s2.pop()); + } + + return result; + } + + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz 使用堆栈检查字符串s中的括号是不是成对出现的。 例如s = + * "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true 如果 s = "([b{x]y})", + * 则该字符串中的括号不是成对出现的, 该方法返回false; + * + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + if (s.length() == 0) { + return false; + } + + Stack s2 = new Stack(); + for (int i = 0; i < s.length(); i++) { + char c1 = s.charAt(i); + if (c1 != ')' && c1 != ']' && c1 != '}') { + s2.push(c1); + } else { + char c2 = getOpChar(s2); + if (!isPair(c1, c2)) { + return false; + } + } + } + + return true; + } + + private static boolean isPair(char c1, char c2) { + if (c1 == ')' && c2 == '(') { + return true; + } + + if (c1 == ']' && c2 == '[') { + return true; + } + + if (c1 == '}' && c2 == '{') { + return true; + } + + return false; + } + + private static char getOpChar(Stack s2) { + char c2 = s2.pop(); + while (c2 != ')' && c2 != ']' && c2 != '}' && + c2 != '(' && c2 != '[' && c2 != '{' && !s2.isEmpty()) { + c2 = s2.pop(); + } + return c2; + } + +} diff --git a/group12/382266293/coding/basic/stack/StackUtilTest.java b/group12/382266293/coding/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..9180c4816e --- /dev/null +++ b/group12/382266293/coding/basic/stack/StackUtilTest.java @@ -0,0 +1,85 @@ +package stack; + +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.Stack; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +public class StackUtilTest { + + Stack s; + @Before + public void setUp() throws Exception { + s = new Stack(); + } + + @After + public void tearDown() throws Exception { + s = null; + } + + @Test + public void testReverse() { + for(int i = 5; i >= 1; i--) { + s.push(i); + } + + StackUtil.reverse(s); + assertEquals(s.toString(),"[1, 2, 3, 4, 5]"); + + } + + @Test + public void testRemove() { + for(int i = 5; i >= 1; i--) { + s.push(i); + } + + StackUtil.remove(s,2); + assertEquals(s.toString(),"[5, 4, 3, 1]"); + + StackUtil.remove(s,5); + assertEquals(s.toString(),"[4, 3, 1]"); + + StackUtil.remove(s,1); + assertEquals(s.toString(),"[4, 3]"); + + s = new Stack(); + assertEquals(s.toString(),"[]"); + } + + @Test + public void testGetTop() { + for(int i = 5; i >= 1; i--) { + s.push(i); + } + + Object[] o = StackUtil.getTop(s,2); + + assertEquals(s.toString(),"[5, 4, 3, 2, 1]"); + assertEquals(Arrays.toString(o),"[1, 2]"); + + o = StackUtil.getTop(s,6); + assertEquals(Arrays.toString(o),"[1, 2, 3, 4, 5]"); + + o = StackUtil.getTop(s,0); + assertEquals(Arrays.toString(o),"[]"); + } + + @Test + public void testIsValidPairs() { + + String s1 = "([e{d}f])"; + assertEquals(true,StackUtil.isValidPairs(s1)); + + s1 = "([b{x]y})"; + assertEquals(false,StackUtil.isValidPairs(s1)); + + } + +} diff --git a/group12/382266293/coding/basic/stack/expr/InfixExpr.java b/group12/382266293/coding/basic/stack/expr/InfixExpr.java new file mode 100644 index 0000000000..eade1dc743 --- /dev/null +++ b/group12/382266293/coding/basic/stack/expr/InfixExpr.java @@ -0,0 +1,18 @@ +package stack.expr; + +public class InfixExpr { + String expr = null; + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + + return 0.0f; + } + + + + +} diff --git a/group12/382266293/coding/basic/stack/expr/InfixExprTest.java b/group12/382266293/coding/basic/stack/expr/InfixExprTest.java new file mode 100644 index 0000000000..bb047629bd --- /dev/null +++ b/group12/382266293/coding/basic/stack/expr/InfixExprTest.java @@ -0,0 +1,48 @@ +package stack.expr; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class InfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + //InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); + { + InfixExpr expr = new InfixExpr("2+3*4+5"); + Assert.assertEquals(19.0, expr.evaluate(), 0.001f); + } + { + InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); + Assert.assertEquals(100.0, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("3*20/2"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("20/2*3"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("10-30+50"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + } + +} diff --git a/group12/382266293/src/array/ArrayUtil.java b/group12/382266293/src/array/ArrayUtil.java index 8412a68f48..ea847fd386 100644 --- a/group12/382266293/src/array/ArrayUtil.java +++ b/group12/382266293/src/array/ArrayUtil.java @@ -6,40 +6,37 @@ import collection.Iterator; import collection.concrete.ArrayList; - - public class ArrayUtil { - + /** - * 给定一个整形数组a , 对该数组的值进行置换 - 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] - 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] + * 给定一个整形数组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){ - + public void reverseArray(int[] origin) { + int temp; int index = origin.length - 1; - int numbersToReverse = origin.length/2; - for (int i = 0; i < numbersToReverse ; i++) { + int numbersToReverse = origin.length / 2; + for (int i = 0; i < numbersToReverse; i++) { temp = origin[i]; origin[i] = origin[index - i]; origin[index - i] = temp; } } - /** - * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} - * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: - * {1,3,4,5,6,6,5,4,7,6,7,5} + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: {1,3,4,5,6,6,5,4,7,6,7,5} + * * @param oldArray * @return */ - public int[] removeZero(int[] oldArray){ - + public int[] removeZero(int[] oldArray) { + BitSet check = new BitSet(oldArray.length); boolean isZero; for (int i = 0; i < oldArray.length; i++) { @@ -47,32 +44,32 @@ public int[] removeZero(int[] oldArray){ check.set(i, isZero); } - int newSize = oldArray.length-check.cardinality(); + int newSize = oldArray.length - check.cardinality(); int[] newArr = new int[newSize]; - + int nextIndex = check.nextClearBit(0); - for(int i = 0 ; i < newSize ; i++) { + for (int i = 0; i < newSize; i++) { newArr[i] = oldArray[nextIndex]; - nextIndex = check.nextClearBit(nextIndex+1); + nextIndex = check.nextClearBit(nextIndex + 1); } return newArr; } - /** - * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 - * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * 给定两个已经排序好的整形数组, 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){ - + + public int[] merge(int[] array1, int[] array2) { + int len1 = array1.length; int len2 = array2.length; - int len3 = array1[len1-1] < array2[len2-1] ? array2[len2-1] + 1: array1[len1-1] + 1; + int len3 = array1[len1 - 1] < array2[len2 - 1] ? array2[len2 - 1] + 1 : array1[len1 - 1] + 1; int[] newArr = new int[len3]; initialArray(newArr, -1); for (int i = 0; i < len1; i++) { @@ -88,24 +85,24 @@ public int[] merge(int[] array1, int[] array2){ } return Arrays.copyOf(newArr, mergedLength); } - + public static void initialArray(int[] arr, int j) { for (int i = 0; i < arr.length; i++) { arr[i] = j; } } - + /** * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size - * 注意,老数组的元素在新数组中需要保持 - * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * 注意,老数组的元素在新数组中需要保持 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 * [2,3,6,0,0,0] + * * @param oldArray * @param size * @return */ - public int[] grow(int [] oldArray, int size){ - + public int[] grow(int[] oldArray, int size) { + int[] newArr = new int[oldArray.length + size]; for (int i = 0; i < oldArray.length; i++) { newArr[i] = oldArray[i]; @@ -113,39 +110,38 @@ public int[] grow(int [] oldArray, int size){ return newArr; } - /** - * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 - * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] - * max = 1, 则返回空数组 [] + * 斐波那契数列为: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){ + public int[] fibonacci(int max) { if (max == 1) return new int[0]; int[] result = new int[max]; result[0] = result[1] = 1; int count = 0; - for (int i = 2, j = 0; j < max ; i++) { - result[i] = result[i-1] + result[i-2]; + for (int i = 2, j = 0; j < max; i++) { + result[i] = result[i - 1] + result[i - 2]; j = result[i]; count++; } return Arrays.copyOf(result, ++count); } - + /** - * 返回小于给定最大值max的所有素数数组 - * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * 返回小于给定最大值max的所有素数数组 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * * @param max * @return */ - public int[] getPrimes(int max){ - + public int[] getPrimes(int max) { + String temp = ""; - for(int i = 0; i < max; i++) { - if(isPrime(i)) { + for (int i = 0; i < max; i++) { + if (isPrime(i)) { temp += i + " "; } } @@ -154,82 +150,77 @@ public int[] getPrimes(int max){ for (int i = 0; i < result.length; i++) { result[i] = Integer.parseInt(tempArr[i]); } - + return result; } - + public static boolean isPrime(int num) { - + if (num <= 1) return false; - + if (num == 2) return true; - - for(int i = 2; i <= Math.sqrt(num) + 1; i++) { + + for (int i = 2; i <= Math.sqrt(num) + 1; i++) { if (num % i == 0) return false; } - + return true; } - /** - * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 - * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * * @param max * @return */ - public int[] getPerfectNumbers(int max){ - + public int[] getPerfectNumbers(int max) { + int count = 0; ArrayList myList = new ArrayList(); - for(int i = 1; i < max; i++) { - if(isPerfectNum(i)) { + for (int i = 1; i < max; i++) { + if (isPerfectNum(i)) { count++; myList.add(i); } } - int[] result = new int[count]; + int[] result = new int[count]; Iterator iterator = myList.iterator(); for (int i = 0; i < count; i++) { result[i] = iterator.next(); } return result; } - - + public static boolean isPerfectNum(int num) { - + int sum = 0; - for (int i = 1; i <= num/2; i++) { + for (int i = 1; i <= num / 2; i++) { if (num % i == 0) sum += i; } - + return (num == sum) ? true : false; } - /** - * 用seperator 把数组 array给连接起来 - * 例如array= [3,8,9], seperator = "-" - * 则返回值为"3-8-9" + * 用seperator 把数组 array给连接起来 例如array= [3,8,9], seperator = "-" 则返回值为"3-8-9" + * * @param array * @param s * @return */ - public String join(int[] array, String seperator){ + public String join(int[] array, String seperator) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < array.length; i++) { sb.append(array[i]); - if (i < array.length-1) + if (i < array.length - 1) sb.append(seperator); } return sb.toString(); } - } \ No newline at end of file diff --git a/group12/382266293/src/array/ArrayUtilTest.java b/group12/382266293/src/array/ArrayUtilTest.java index 42085c1e25..031ef6c09b 100644 --- a/group12/382266293/src/array/ArrayUtilTest.java +++ b/group12/382266293/src/array/ArrayUtilTest.java @@ -9,14 +9,11 @@ import org.junit.Before; import org.junit.Test; - - - public class ArrayUtilTest { private int[] actual; ArrayUtil au = new ArrayUtil(); - + @Before public void setUp() throws Exception { @@ -27,34 +24,33 @@ public void tearDown() throws Exception { actual = null; } - @Test public void testReverseArray() { - + int size = getRandomNumber(); int[] expected = getRandomIntArray(size); actual = Arrays.copyOf(expected, size); - + au.reverseArray(actual); - + for (int i = 0; i < size; i++) { - assertEquals(expected[i], actual[size-1-i]); + assertEquals(expected[i], actual[size - 1 - i]); } - + } @Test public void testRemoveZero() { - + int size = getRandomNumber(10000); int[] expected = getRandomIntArray(size); - int zeros = getRandomNumber(size-1); + int zeros = getRandomNumber(size - 1); TreeSet t = new TreeSet(); while (t.size() != zeros) { t.add(getRandomNumber(size)); } - + for (Integer i : t) { expected[i] = 0; } @@ -62,17 +58,17 @@ public void testRemoveZero() { int expectedSize = size - zeros; actual = au.removeZero(expected); assertEquals(expectedSize, actual.length); - + for (int i = 0, j = 0; i < size; i++) { if (expected[i] != 0) assertEquals(expected[i], actual[j++]); } - + } @Test public void testMerge() { - int[] arr1 = getRandomIntArray(getRandomNumber()); + int[] arr1 = getRandomIntArray(getRandomNumber()); int[] arr2 = getRandomIntArray(getRandomNumber()); Arrays.sort(arr1); Arrays.sort(arr2); @@ -85,12 +81,12 @@ public void testMerge() { } int[] actual = new int[arr1.length + arr2.length]; actual = au.merge(arr1, arr2); - + assertEquals(t.size(), actual.length); - + Iterator it = t.iterator(); - for(int i = 0; it.hasNext(); i++) { - assertEquals((int)it.next(), actual[i]); + for (int i = 0; it.hasNext(); i++) { + assertEquals((int) it.next(), actual[i]); } } @@ -100,43 +96,43 @@ public void testGrow() { int[] expected = getRandomIntArray(getRandomNumber()); int growSize = getRandomNumber(); int[] actual = au.grow(expected, growSize); - + assertEquals(expected.length + growSize, actual.length); - + for (int i = 0; i < actual.length; i++) { if (i < expected.length) { assertEquals(expected[i], actual[i]); } else { assertEquals(0, actual[i]); - } + } } } @Test public void testFibonacci() { - int[] expected = new int[] {1, 1, 2, 3, 5, 8, 13}; + int[] expected = new int[] { 1, 1, 2, 3, 5, 8, 13 }; int[] acutal = new int[expected.length]; actual = au.fibonacci(15); - assertArrayEquals(expected,actual); + assertArrayEquals(expected, actual); } @Test public void testGetPrimes() { - - int[] expected = new int[] {2,3,5,7,11,13,17,19}; + + int[] expected = new int[] { 2, 3, 5, 7, 11, 13, 17, 19 }; int[] acutal = new int[expected.length]; actual = au.getPrimes(23); - assertArrayEquals(expected,actual); + assertArrayEquals(expected, actual); } @Test public void testGetPerfectNumbers() { - - int[] expected = new int[] {6, 28, 496, 8128}; + + int[] expected = new int[] { 6, 28, 496, 8128 }; int[] acutal = new int[expected.length]; actual = au.getPerfectNumbers(10000); - assertArrayEquals(expected,actual); + assertArrayEquals(expected, actual); } @Test @@ -145,9 +141,9 @@ public void testJoin() { int[] expected = getRandomIntArray(getRandomNumber()); String seperator = "-"; String joinedString = au.join(expected, seperator); - + String[] actual = joinedString.split(seperator); - + assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; i++) { assertEquals(expected[i], Integer.parseInt(actual[i])); diff --git a/group12/382266293/src/com/coderising/download/DownloadThread.java b/group12/382266293/src/com/coderising/download/DownloadThread.java index d1e1f04c47..38f92f6677 100644 --- a/group12/382266293/src/com/coderising/download/DownloadThread.java +++ b/group12/382266293/src/com/coderising/download/DownloadThread.java @@ -7,8 +7,7 @@ import com.coderising.download.api.Connection; - -public class DownloadThread extends Thread{ +public class DownloadThread extends Thread { Connection conn; int startPos; @@ -16,15 +15,16 @@ public class DownloadThread extends Thread{ private String dest; private FileDownloader fileDownloader; - public DownloadThread( Connection conn, int startPos, int endPos){ - - this.conn = conn; + public DownloadThread(Connection conn, int startPos, int endPos) { + + this.conn = conn; this.startPos = startPos; this.endPos = endPos; } + @Override - public void run(){ - System.out.println(this.getName()+" is running"); + public void run() { + System.out.println(this.getName() + " is running"); RandomAccessFile raf = null; try { byte[] buffer = conn.read(startPos, endPos); @@ -36,7 +36,7 @@ public void run(){ e.printStackTrace(); } finally { conn.close(); - System.out.println(this.getName()+" finished"); + System.out.println(this.getName() + " finished"); try { if (raf != null) @@ -48,7 +48,7 @@ public void run(){ } } } - + public void setFileDownloader(FileDownloader fileDownloader) { this.fileDownloader = fileDownloader; } @@ -56,15 +56,14 @@ public void setFileDownloader(FileDownloader fileDownloader) { public void notifyFinished() { fileDownloader.setThreadFinished(); } - + public void setDest(String dest) { this.dest = dest; } - + public void close() { this.conn.close(); - + } - } diff --git a/group12/382266293/src/com/coderising/download/DownloadUtil.java b/group12/382266293/src/com/coderising/download/DownloadUtil.java index b01200c51d..c169214476 100644 --- a/group12/382266293/src/com/coderising/download/DownloadUtil.java +++ b/group12/382266293/src/com/coderising/download/DownloadUtil.java @@ -66,8 +66,8 @@ public static boolean rename(String from, String to) { public static void printDownloadReport(int length, long start, long end) { int time = (int) ((end - start) / 1000); - float speed = (float)length / 1024 / 1024 / time; - System.out.println("共耗时:" + time + "s,下载速度: " + (float)(Math.round(speed*100))/100 + "Mb/s"); + float speed = (float) length / 1024 / 1024 / time; + System.out.println("共耗时:" + time + "s,下载速度: " + (float) (Math.round(speed * 100)) / 100 + "Mb/s"); } } \ No newline at end of file diff --git a/group12/382266293/src/com/coderising/download/FileDownloader.java b/group12/382266293/src/com/coderising/download/FileDownloader.java index c756248bb1..671ff7243c 100644 --- a/group12/382266293/src/com/coderising/download/FileDownloader.java +++ b/group12/382266293/src/com/coderising/download/FileDownloader.java @@ -45,7 +45,6 @@ public void execute() { Connection conn = cm.open(this.url); int length = conn.getContentLength(); - System.out.println("file length:" + length); setLocation("C:\\"); @@ -53,7 +52,7 @@ public void execute() { setFileName(name); setTempName(name); checkLength(length, conn); - + DownloadUtil.createTempFile(tempName, length); int connNumbers = DownloadUtil.calculateConnects(length); @@ -153,7 +152,6 @@ private void setAndStartThreadPool(Connection conn, DownloadThread[] threadPool, } threadPool[i] = new DownloadThread(con, beginPos, endPos); setAndStartThread(threadPool[i], tempName); - } } diff --git a/group12/382266293/src/com/coderising/download/FileDownloaderTest.java b/group12/382266293/src/com/coderising/download/FileDownloaderTest.java index ae24faa19f..88a5dba40e 100644 --- a/group12/382266293/src/com/coderising/download/FileDownloaderTest.java +++ b/group12/382266293/src/com/coderising/download/FileDownloaderTest.java @@ -22,7 +22,6 @@ public void tearDown() throws Exception { public static String qq = "http://sw.bos.baidu.com/sw-search-sp/software/89179b0b248b1/QQ_8.9.20026.0_setup.exe"; public static String picture = "http://image.beekka.com/blog/201304/bg2013042401.jpg"; public static String foxmail = "http://sw.bos.baidu.com/sw-search-sp/software/6c7bb8b6674d0/fm728chb379_7.2.8.379_setup.exe"; - @Test public void testDownload() { diff --git a/group12/382266293/src/com/coderising/download/api/Connection.java b/group12/382266293/src/com/coderising/download/api/Connection.java index 63d9fc7b19..11a0eab3d8 100644 --- a/group12/382266293/src/com/coderising/download/api/Connection.java +++ b/group12/382266293/src/com/coderising/download/api/Connection.java @@ -5,23 +5,31 @@ public interface Connection { /** * 给定开始和结束位置, 读取数据, 返回值是字节数组 - * @param startPos 开始位置, 从0开始 - * @param endPos 结束位置 + * + * @param startPos + * 开始位置, 从0开始 + * @param endPos + * 结束位置 * @return */ - public byte[] read(int startPos,int endPos) throws IOException; + public byte[] read(int startPos, int endPos) throws IOException; + /** * 得到数据内容的长度 + * * @return */ public int getContentLength(); - + /** * 关闭连接 */ public void close(); + public String getFileName(); + public void setFinished(); + public boolean isFinished(); } diff --git a/group12/382266293/src/com/coderising/download/api/ConnectionManager.java b/group12/382266293/src/com/coderising/download/api/ConnectionManager.java index 17f1e544b1..c305248608 100644 --- a/group12/382266293/src/com/coderising/download/api/ConnectionManager.java +++ b/group12/382266293/src/com/coderising/download/api/ConnectionManager.java @@ -3,11 +3,12 @@ public interface ConnectionManager { /** * 给定一个url , 打开一个连接 + * * @param url * @return */ - + final int MAX_CONNECTION_SIZE = 100; - + public Connection open(String url) throws ConnectionException; } diff --git a/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java b/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java index 61ed430106..a4fa5c15ad 100644 --- a/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java +++ b/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java @@ -10,14 +10,14 @@ import sun.net.www.protocol.http.HttpURLConnection; -public class ConnectionImpl implements Connection{ +public class ConnectionImpl implements Connection { private ConnectionManager cm; private static int buffer_size = 1024; private HttpURLConnection httpConn; private URL url; private boolean finished = false; - + public ConnectionImpl(ConnectionManager cm, String _url) { this.cm = cm; try { @@ -35,28 +35,28 @@ public byte[] read(int startPos, int endPos) throws IOException { try { httpConn = (HttpURLConnection) url.openConnection(); httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); - in = httpConn.getInputStream(); + in = httpConn.getInputStream(); out = new ByteArrayOutputStream(); in = httpConn.getInputStream(); - //in.skip(startPos); - + // in.skip(startPos); + int len = 0; byte[] b = new byte[1024]; - while((len = in.read(b)) != -1) { + while ((len = in.read(b)) != -1) { out.write(b, 0, len); } int totalLen = endPos - startPos + 1; - - if (out.size() > totalLen) { + + if (out.size() > totalLen) { byte[] data = out.toByteArray(); return data; } - + return out.toByteArray(); - + } catch (IOException e) { e.printStackTrace(); - } + } return null; } @@ -65,18 +65,18 @@ public int getContentLength() { int len = httpConn.getContentLength(); return len; - + } @Override public void close() { - httpConn.disconnect(); + httpConn.disconnect(); } @Override public String getFileName() { String fileName = httpConn.getURL().getFile(); - fileName = fileName.substring(fileName.lastIndexOf('/')+1); + fileName = fileName.substring(fileName.lastIndexOf('/') + 1); return fileName; } @@ -90,5 +90,4 @@ public boolean isFinished() { return finished; } - } diff --git a/group12/382266293/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group12/382266293/src/com/coderising/download/impl/ConnectionManagerImpl.java index 4d44301b0d..122073e37b 100644 --- a/group12/382266293/src/com/coderising/download/impl/ConnectionManagerImpl.java +++ b/group12/382266293/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -11,7 +11,7 @@ public class ConnectionManagerImpl implements ConnectionManager { private int connections = 0; private String url; - + public ConnectionManagerImpl() { this.connections = 0; } @@ -24,12 +24,12 @@ public Connection open(String url) throws ConnectionException { Connection conn = null; try { address = new URL(url); - conn = new ConnectionImpl(this,url); + conn = new ConnectionImpl(this, url); connections++; return conn; } catch (IOException e) { e.printStackTrace(); - } + } return null; } @@ -43,4 +43,3 @@ private void checkConnectionSize() { } } - diff --git a/group12/382266293/src/com/coderising/download/impl/NoFreeSourceException.java b/group12/382266293/src/com/coderising/download/impl/NoFreeSourceException.java index f2f68c3aa0..909a17a29b 100644 --- a/group12/382266293/src/com/coderising/download/impl/NoFreeSourceException.java +++ b/group12/382266293/src/com/coderising/download/impl/NoFreeSourceException.java @@ -2,7 +2,6 @@ public class NoFreeSourceException extends Exception { - public NoFreeSourceException(String string) { super(string); } diff --git a/group12/382266293/src/com/coderising/jvm/attr/AttributeInfo.java b/group12/382266293/src/com/coderising/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..89fb53394e --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/attr/AttributeInfo.java @@ -0,0 +1,19 @@ +package com.coderising.jvm.attr; + +public abstract class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + int attrNameIndex; + int attrLen ; + public AttributeInfo(int attrNameIndex, int attrLen) { + + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } + + +} diff --git a/group12/382266293/src/com/coderising/jvm/attr/CodeAttr.java b/group12/382266293/src/com/coderising/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..68a628ec61 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/attr/CodeAttr.java @@ -0,0 +1,118 @@ +package com.coderising.jvm.attr; + +import java.io.UnsupportedEncodingException; + +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.loader.ByteCodeIterator; + + +public class CodeAttr extends AttributeInfo { + private int maxStack ; + private int maxLocals ; + private int codeLen ; + private String code; + public String getCode() { + return code; + } + + //private ByteCodeCommand[] cmds ; + //public ByteCodeCommand[] getCmds() { + // return cmds; + //} + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + //this.cmds = cmds; + } + + public void setLineNumberTable(LineNumberTable t) { + this.lineNumTable = t; + } + + public void setLocalVariableTable(LocalVariableTable t) { + this.localVarTable = t; + } + + public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2ToInt(); + + System.out.println("attrIndex " + attrNameIndex); + + int attrLen = iter.nextU4ToInt(); + + int maxStack = iter.nextU2ToInt(); + + int maxLocals = iter.nextU2ToInt(); + + int codeLen = iter.nextU4ToInt(); + + System.out.println("codeLen " + codeLen); + + CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, maxLocals, codeLen, "Code"); + + String code = iter.nextUxToHexString(codeLen); + + System.out.println("Code is " + code); + + int exceptionTableLen = iter.nextU2ToInt(); + + if (exceptionTableLen > 0) { + + String exTable = iter.nextUxToHexString(exceptionTableLen); + + System.out.println("exception encounted " + exTable); + } + + int sub_attrNum = iter.nextU2ToInt(); + + for (int i = 0; i < sub_attrNum; i++) { + + int subAttrNameIndex = iter.nextU2ToInt(); + String subAttrName = clzFile.getConstantPool().getUTF8String(subAttrNameIndex); + System.out.println("subAttrNameIndex is " + subAttrName); + iter.back(2); + + if (AttributeInfo.LINE_NUM_TABLE.equalsIgnoreCase(subAttrName)) { + + LineNumberTable lnt = LineNumberTable.parse(iter); + codeAttr.setLineNumberTable(lnt); + + } else if (AttributeInfo.LOCAL_VAR_TABLE.equalsIgnoreCase(subAttrName)) { + + LocalVariableTable lvt = LocalVariableTable.parse(iter); + codeAttr.setLocalVariableTable(lvt); + + } else if (AttributeInfo.STACK_MAP_TABLE.equalsIgnoreCase(subAttrName)) { + + StackMapTable smt = StackMapTable.parse(iter); + codeAttr.setStackMapTable(smt); + + } else { + throw new RuntimeException(subAttrName + "not implemented yet"); + } + + } + + return codeAttr; + } + + + private void setStackMapTable(StackMapTable t) { + this.stackMapTable = t; + + } + + + + + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java b/group12/382266293/src/com/coderising/jvm/attr/LineNumberTable.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java rename to group12/382266293/src/com/coderising/jvm/attr/LineNumberTable.java diff --git a/group12/382266293/src/com/coderising/jvm/attr/LocalVariableItem.java b/group12/382266293/src/com/coderising/jvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..3eb2654e36 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/attr/LocalVariableItem.java @@ -0,0 +1,39 @@ +package com.coderising.jvm.attr; + +public class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getNameIndex() { + return nameIndex; + } + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + public int getDescIndex() { + return descIndex; + } + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java b/group12/382266293/src/com/coderising/jvm/attr/LocalVariableTable.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java rename to group12/382266293/src/com/coderising/jvm/attr/LocalVariableTable.java diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java b/group12/382266293/src/com/coderising/jvm/attr/StackMapTable.java similarity index 100% rename from liuxin/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java rename to group12/382266293/src/com/coderising/jvm/attr/StackMapTable.java diff --git a/group12/382266293/src/com/coderising/jvm/clz/AccessFlag.java b/group12/382266293/src/com/coderising/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..17dd61f8b6 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/clz/AccessFlag.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.clz; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass() { + return (this.flagValue & 0x0001) != 0; + } + + public boolean isFinalClass() { + return (this.flagValue & 0x0010) != 0; + } + + public static AccessFlag parseAccessFlag(ByteCodeIterator iter) { + AccessFlag accessFlag = new AccessFlag(iter.nextU2ToInt()); + return accessFlag; + } +} \ No newline at end of file diff --git a/group12/382266293/src/com/coderising/jvm/clz/ClassFile.java b/group12/382266293/src/com/coderising/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..6e37d03643 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,118 @@ +package com.coderising.jvm.clz; + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + private List fields = new ArrayList(); + private List methods = new ArrayList(); + + public ClassIndex getClzIndex() { + return clzIndex; + } + + public AccessFlag getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + public ConstantPool getConstantPool() { + return pool; + } + + public int getMinorVersion() { + return minorVersion; + } + + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + + public int getMajorVersion() { + return majorVersion; + } + + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + public void print() { + + if (this.accessFlag.isPublicClass()) { + System.out.println("Access flag : public "); + } + System.out.println("Class Name:" + getClassName()); + + System.out.println("Super Class Name:" + getSuperClassName()); + + } + + private String getClassName() { + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo) this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + + private String getSuperClassName() { + ClassInfo superClass = (ClassInfo) this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } + + public List getFields() { + + return fields; + } + + public void setFields(List fields) { + + this.fields = fields; + + } + + public void addField(Field field) { + + this.fields.add(field); + + } + + public List getMethods() { + + return methods; + } + + public void setMethods(List methods) { + + this.methods = methods; + + } + + public void addMethod(Method method) { + + this.methods.add(method); + + } +} diff --git a/group12/382266293/src/com/coderising/jvm/clz/ClassIndex.java b/group12/382266293/src/com/coderising/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..0212bc9fb3 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/clz/ClassIndex.java @@ -0,0 +1,22 @@ +package com.coderising.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + + public int getSuperClassIndex() { + return superClassIndex; + } + + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group12/382266293/src/com/coderising/jvm/constant/ClassInfo.java b/group12/382266293/src/com/coderising/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..4b593e7347 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/constant/ClassInfo.java @@ -0,0 +1,28 @@ +package com.coderising.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index; + + public ClassInfo(ConstantPool pool) { + super(pool); + } + + public int getUtf8Index() { + return utf8Index; + } + + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info) constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group12/382266293/src/com/coderising/jvm/constant/ConstantInfo.java b/group12/382266293/src/com/coderising/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..96845046b3 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/constant/ConstantInfo.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo() { + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + pool.addConstantInfo(this); + } + + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group12/382266293/src/com/coderising/jvm/constant/ConstantPool.java b/group12/382266293/src/com/coderising/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..95c44dde8f --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/constant/ConstantPool.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + public ConstantPool() { + + } + + public void addConstantInfo(ConstantInfo info) { + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index) { + //System.out.println(this.constantInfos.get(index)); + return this.constantInfos.get(index); + } + + public String getUTF8String(int index) { + return ((UTF8Info) this.constantInfos.get(index)).getValue(); + } + + public Object getSize() { + return this.constantInfos.size() - 1; + } +} diff --git a/group12/382266293/src/com/coderising/jvm/constant/FieldRefInfo.java b/group12/382266293/src/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..e9f34e550c --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,58 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo { + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() + " : " + typeInfo.getName() + ":" + typeInfo.getTypeInfo() + "]"; + } + + public String getClassName() { + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info) this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group12/382266293/src/com/coderising/jvm/constant/MethodRefInfo.java b/group12/382266293/src/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..d58de16f72 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,57 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + + return getClassName() + " : " + this.getMethodName() + " : " + this.getParamAndReturnType(); + } + + public String getClassName() { + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo) pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo) pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + +} diff --git a/group12/382266293/src/com/coderising/jvm/constant/NameAndTypeInfo.java b/group12/382266293/src/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..a792e2dc13 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,48 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo { + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + + public void setIndex1(int index1) { + this.index1 = index1; + } + + public int getIndex2() { + return index2; + } + + public void setIndex2(int index2) { + this.index2 = index2; + } + + public int getType() { + return type; + } + + public String getName() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info) pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info) pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString() { + return "(" + getName() + "," + getTypeInfo() + ")"; + } +} diff --git a/group12/382266293/src/com/coderising/jvm/constant/NullConstantInfo.java b/group12/382266293/src/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..7d1abf7699 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,14 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo() { + + } + + @Override + public int getType() { + return -1; + } + +} diff --git a/group12/382266293/src/com/coderising/jvm/constant/StringInfo.java b/group12/382266293/src/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..0ea1f6bdac --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,27 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo { + private int type = ConstantInfo.STRING_INFO; + private int index; + + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public String toString() { + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group12/382266293/src/com/coderising/jvm/constant/UTF8Info.java b/group12/382266293/src/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..a7e88969a4 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,37 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo { + private int type = ConstantInfo.UTF8_INFO; + private int length; + private String value; + + public UTF8Info(ConstantPool pool) { + super(pool); + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getType() { + return type; + } + + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value + ")]"; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} diff --git a/group12/382266293/src/com/coderising/jvm/field/Field.java b/group12/382266293/src/com/coderising/jvm/field/Field.java new file mode 100644 index 0000000000..2b0c549685 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/field/Field.java @@ -0,0 +1,48 @@ +package com.coderising.jvm.field; + +import com.coderising.jvm.clz.AccessFlag; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.loader.ByteCodeIterator; + + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private ConstantPool pool; + + public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + + + @Override + public String toString() { + return pool.getUTF8String(nameIndex) + ":" + pool.getUTF8String(descriptorIndex) ; + } + + public static Field parse(ConstantPool pool,ByteCodeIterator iter){ + + int access_flags = iter.nextU2ToInt(); + int name_index = iter.nextU2ToInt(); + int descriptor_index = iter.nextU2ToInt(); + int attrbutes_count = iter.nextU2ToInt(); + + if (attrbutes_count != 0) { + throw new RuntimeException("field attrbutes_count is " + attrbutes_count); + } + + Field field = new Field(access_flags,name_index,descriptor_index,pool); + + return field; + } + +} diff --git a/group12/382266293/src/com/coderising/jvm/loader/ByteCodeIterator.java b/group12/382266293/src/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..4b554a434a --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,69 @@ +package com.coderising.jvm.loader; + +import com.coderising.jvm.util.Util; + +public class ByteCodeIterator { + + private byte[] codes = null; + private int currPos = 0; + + public ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public String nextU4ToHexString() { + byte[] u4 = new byte[] { codes[currPos++], codes[currPos++], codes[currPos++], codes[currPos++] }; + return Util.byteToHexString(u4); + } + + public int nextU1ToInt() { + byte[] u1 = new byte[] { codes[currPos++] }; + return Util.byteToInt(u1); + + } + + public int nextU2ToInt() { + byte[] u2 = new byte[] { codes[currPos++], codes[currPos++] }; + return Util.byteToInt(u2); + } + + public int nextU4ToInt() { + byte[] u4 = new byte[] { codes[currPos++], codes[currPos++], codes[currPos++], codes[currPos++] }; + return Util.byteToInt(u4); + } + + + public byte[] nextNbytesToHexString(int length) { + byte[] bytes = new byte[length]; + int len = currPos + length; + for(int j = 0; currPos < len; j++) { + bytes[j] = codes[currPos++]; + } + + return bytes; + } + + public String nextUxToHexString(int length) { + byte[] codes = nextNbytesToHexString(length); + return byteToHexString(codes); + } + + public String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + + public void back(int i) { + currPos = currPos - 2; + } + +} diff --git a/group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java b/group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java index 9ba4ff935b..71a8b6fefa 100644 --- a/group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java +++ b/group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -4,9 +4,12 @@ import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; +import com.coderising.jvm.clz.ClassFile; + public class ClassFileLoader { private List clzPaths = new ArrayList(); @@ -17,6 +20,14 @@ public byte[] readBinaryCode(String className) { return loadClassFile(clzFileName); } + public ClassFile loadClass(String className) throws UnsupportedEncodingException { + + ClassFileParser clzParser = new ClassFileParser(); + byte[] codes = readBinaryCode(className); + ClassFile clzFile = clzParser.parse(codes); + return clzFile; + } + @SuppressWarnings("resource") private byte[] loadClassFile(String clzFileName) { File classFile = getClassFile(clzFileName); diff --git a/group12/382266293/src/com/coderising/jvm/loader/ClassFileParser.java b/group12/382266293/src/com/coderising/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..e1c997d3d0 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/loader/ClassFileParser.java @@ -0,0 +1,191 @@ +package com.coderising.jvm.loader; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; + +import com.coderising.jvm.clz.AccessFlag; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.FieldRefInfo; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.NullConstantInfo; +import com.coderising.jvm.constant.StringInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; +import com.coderising.jvm.util.Util; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + + ClassFile clzFile = new ClassFile(); + + ByteCodeIterator iter = new ByteCodeIterator(codes); + + String magicNumber = iter.nextU4ToHexString(); + if ("cafebabe".equals(magicNumber) == false) { + throw new RuntimeException("invalide class file!" + magicNumber); + } + + int minorVersion = iter.nextU2ToInt(); + System.out.println("minorVersion is " + minorVersion); + clzFile.setMinorVersion(minorVersion); + + int majorVersion = iter.nextU2ToInt(); + System.out.println("majorVersion is " + majorVersion); + clzFile.setMajorVersion(majorVersion); + + + ConstantPool pool = parseConstantPool(iter); + clzFile.setConstPool(pool); + + + AccessFlag accessFlag = parseAccessFlag(iter); + clzFile.setAccessFlag(accessFlag); + + ClassIndex classIndex = parseClassIndex(iter); + clzFile.setClassIndex(classIndex); + + parseInterfaces(iter); + + parseFields(clzFile, iter); + + parseMethods(clzFile, iter); + + return clzFile; + } + + private void parseMethods(ClassFile clzFile, ByteCodeIterator iter) { + + int methodNum = iter.nextU2ToInt(); + + ConstantPool pool = clzFile.getConstantPool(); + for (int i = 0; i < methodNum; i++) { + Method method = Method.parse(clzFile,iter); + clzFile.addMethod(method); + } + + } + + private void parseFields(ClassFile clzFile, ByteCodeIterator iter) { + + int fieldNum = iter.nextU2ToInt(); + + ConstantPool pool = clzFile.getConstantPool(); + for (int i = 0; i < fieldNum; i++) { + Field field = Field.parse(pool,iter); + clzFile.addField(field); + } + + } + + private void parseInterfaces(ByteCodeIterator iter) { + int interfaceNum = iter.nextU2ToInt(); + + if (0 != interfaceNum) { + throw new RuntimeException("interface parser not finsihed yet, pls check!"); + } + + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + + return AccessFlag.parseAccessFlag(iter); + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + + int thisClassIndex = iter.nextU2ToInt(); + int superClassIndex = iter.nextU2ToInt(); + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(thisClassIndex); + classIndex.setSuperClassIndex(superClassIndex); + return classIndex; + + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + + int constantsNum = iter.nextU2ToInt(); + System.out.println("constantsNum is " + constantsNum); + + ConstantPool pool = new ConstantPool(); + + pool.addConstantInfo(new NullConstantInfo()); + + for (int i = 1; i < constantsNum; i++) { + + int tag = iter.nextU1ToInt(); + + if (tag == 7) { + // Class info + ClassInfo classInfo = new ClassInfo(pool); + int utf8Index = iter.nextU2ToInt(); + classInfo.setUtf8Index(utf8Index); + + + } else if (tag == 1) { + + // utf8-info + UTF8Info utf8Info = new UTF8Info(pool); + int length = iter.nextU2ToInt(); + System.out.println("length is " + length); + utf8Info.setLength(length); + byte[] bytes = iter.nextNbytesToHexString(length); + String value = ""; + try { + value = new String(bytes, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + System.out.println("value is " + value); + utf8Info.setValue(value); + + } else if (tag == 8) { + + // StringInfo + StringInfo stringInfo = new StringInfo(pool); + int stringIndex = iter.nextU2ToInt(); + stringInfo.setIndex(stringIndex); + } else if (tag == 9) { + + // FieldRefInfo + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + int classIndex = iter.nextU2ToInt(); + fieldRefInfo.setClassInfoIndex(classIndex); + int nameAndTypeIndex = iter.nextU2ToInt(); + fieldRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + + } else if (tag == 10) { + + // MethodRefInfo + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + int classIndex = iter.nextU2ToInt(); + methodRefInfo.setClassInfoIndex(classIndex); + int nameAndTypeIndex = iter.nextU2ToInt(); + methodRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + + } else if (tag == 12) { + + // NameAndTypeInfo + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + int index1 = iter.nextU2ToInt(); + nameAndTypeInfo.setIndex1(index1); + int index2 = iter.nextU2ToInt(); + nameAndTypeInfo.setIndex2(index2); + + } + + } + + return pool; + } + +} diff --git a/group12/382266293/src/com/coderising/jvm/method/Method.java b/group12/382266293/src/com/coderising/jvm/method/Method.java new file mode 100644 index 0000000000..3c3e026a40 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/method/Method.java @@ -0,0 +1,81 @@ +package com.coderising.jvm.method; + +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.attr.AttributeInfo; +import com.coderising.jvm.attr.CodeAttr; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.loader.ByteCodeIterator; +import com.sun.org.apache.bcel.internal.classfile.Code; + + + +public class Method { + + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + + private ClassFile clzFile; + + + public ClassFile getClzFile() { + return clzFile; + } + + public int getNameIndex() { + return nameIndex; + } + public int getDescriptorIndex() { + return descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr code) { + this.codeAttr = code; + } + + public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) { + this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ + + int access_flags = iter.nextU2ToInt(); + int name_index = iter.nextU2ToInt(); + int descriptor_index = iter.nextU2ToInt(); + int attrbutes_count = iter.nextU2ToInt(); + System.out.println("count1 = " + attrbutes_count); + + Method method = new Method(clzFile, access_flags,name_index,descriptor_index); + + for (int i = 0; i < attrbutes_count; i++) { + int attr_nameIndex = iter.nextU2ToInt(); + String att_name = clzFile.getConstantPool().getUTF8String(attr_nameIndex); + iter.back(2); + + if (AttributeInfo.CODE.equalsIgnoreCase("Code")) { + CodeAttr codeAttr = CodeAttr.parse(clzFile, iter); + method.setCodeAttr(codeAttr); + } else { + throw new RuntimeException(att_name + "has not been implemented"); + } + + } + + + + return method; + + } +} diff --git a/group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java index fb2f3be0a6..d4f255a763 100644 --- a/group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java +++ b/group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -1,18 +1,41 @@ package com.coderising.jvm.test; +import java.io.UnsupportedEncodingException; import java.util.Arrays; +import java.util.List; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.*; +import com.coderising.jvm.field.Field; import com.coderising.jvm.loader.ClassFileLoader; +import com.coderising.jvm.method.Method; public class ClassFileloaderTest { - static String path1 = "C:\\Users\\Administrator\\git\\coding2017n\\group12\\382266293\\bin"; + static String path1 = "C:\\Users\\steve\\workspace\\coding2017n\\group12\\382266293\\bin"; static String path2 = "C:\temp"; + String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; + + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + String className = "com.coderising.jvm.test.EmployeeV1"; + + try { + clzFile = loader.loadClass(className); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + clzFile.print(); + } @Before public void setUp() throws Exception { @@ -45,7 +68,7 @@ public void testClassFileLength() { byte[] byteCodes = loader.readBinaryCode(className); - // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + // 娉ㄦ剰锛氳繖涓瓧鑺傛暟鍙兘鍜屼綘鐨凧VM鐗堟湰鏈夊叧绯伙紝 浣犲彲浠ョ湅鐪嬬紪璇戝ソ鐨勭被鍒板簳鏈夊澶� Assert.assertEquals(1056, byteCodes.length); } @@ -77,4 +100,162 @@ private String byteToHexString(byte[] codes) { return buffer.toString(); } + @Test + public void testVersion() { + + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool() { + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo) pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + // 鎶芥煡鍑犱釜鍚� + { + MethodRefInfo methodRef = (MethodRefInfo) pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + + @Test + public void testClassIndex() { + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo) clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo) clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + + @Test + public void testReadFields(){ + + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + @Test + public void testMethods(){ + + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } + + } diff --git a/group12/382266293/src/com/coderising/jvm/util/Util.java b/group12/382266293/src/com/coderising/jvm/util/Util.java new file mode 100644 index 0000000000..1f9e087bb9 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/util/Util.java @@ -0,0 +1,22 @@ +package com.coderising.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes) { + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + public static String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group12/382266293/src/com/coderising/litestruts/LoginAction.java b/group12/382266293/src/com/coderising/litestruts/LoginAction.java index a3ce652047..95fd144d4d 100644 --- a/group12/382266293/src/com/coderising/litestruts/LoginAction.java +++ b/group12/382266293/src/com/coderising/litestruts/LoginAction.java @@ -2,38 +2,41 @@ /** * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * * @author liuxin * */ -public class LoginAction{ - private String name ; - private String password; - private String message; +public class LoginAction { + private String name; + private String password; + private String message; - public String getName() { - return name; - } + public String getName() { + return name; + } - public String getPassword() { - return password; - } + 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 String execute() { + if ("test".equals(name) && "1234".equals(password)) { + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } - public void setName(String name){ - this.name = name; - } - public void setPassword(String password){ - this.password = password; - } - public String getMessage(){ - return this.message; - } + public void setName(String name) { + this.name = name; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getMessage() { + return this.message; + } } \ No newline at end of file diff --git a/group12/382266293/src/litestruts/Configuration.java b/group12/382266293/src/litestruts/Configuration.java index 4efedbce67..731a4218b0 100644 --- a/group12/382266293/src/litestruts/Configuration.java +++ b/group12/382266293/src/litestruts/Configuration.java @@ -9,84 +9,84 @@ import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import static util.Print.*; + public class Configuration { - Map actions = new HashMap<>(); + Map actions = new HashMap<>(); private static Configuration cfg = new Configuration(); - + private Configuration() { } + public static Configuration getNewInstance() { - + if (cfg == null) { cfg = new Configuration(); } return cfg; } - + public void parse(String fileName) { - + String src = this.getClass().getPackage().getName(); - String filepath = src.replace(".", "/") + "/" +fileName; + String filepath = src.replace(".", "/") + "/" + fileName; InputStream is = this.getClass().getResourceAsStream("/" + filepath); - + parseXML(is); - + try { is.close(); - } catch (IOException e) { - + } catch (IOException e) { + } - + } - + public void parseXML(InputStream is) { SAXBuilder reader = new SAXBuilder(); - try { + try { Document doc = reader.build(is); Element root = doc.getRootElement(); - - for(Element element : root.getChildren("action")) { - + + for (Element element : root.getChildren("action")) { + String actionName = element.getAttributeValue("name"); String clz = element.getAttributeValue("class"); - ActionCfg ac = new ActionCfg(actionName,clz); - - for(Element e : element.getChildren("result")) { - + ActionCfg ac = new ActionCfg(actionName, clz); + + for (Element e : element.getChildren("result")) { + String result = e.getAttributeValue("name"); String jsp = e.getText().trim(); ac.addViewResult(result, jsp); } - + actions.put(actionName, ac); } - + } catch (JDOMException | IOException e) { e.printStackTrace(); } } - - + public String getClassName(String action) { ActionCfg cfg = this.actions.get(action); if (cfg == null) { return null; } - return cfg.getClassName(); + return cfg.getClassName(); } - - + public String getResultView(String action, String resultName) { ActionCfg cfg = this.actions.get(action); if (cfg == null) { return null; } - return cfg.getViewResult().get(resultName); + return cfg.getViewResult().get(resultName); } public static void main(String[] args) { @@ -94,17 +94,14 @@ public static void main(String[] args) { cfg.parse("struts.xml"); String clz = cfg.getClassName("login"); println(clz); - } - - private static class ActionCfg { - + String name; String clz; - Map viewResult = new HashMap<>(); + Map viewResult = new HashMap<>(); public Map getViewResult() { return viewResult; @@ -117,7 +114,7 @@ public ActionCfg(String name, String clz) { public void addViewResult(String result, String jsp) { viewResult.put(result, jsp); - + } public String getClassName() { @@ -126,10 +123,4 @@ public String getClassName() { } - - - - - - } diff --git a/group12/382266293/src/litestruts/ConfigurationTest.java b/group12/382266293/src/litestruts/ConfigurationTest.java index e9d41a07c9..bf47334da5 100644 --- a/group12/382266293/src/litestruts/ConfigurationTest.java +++ b/group12/382266293/src/litestruts/ConfigurationTest.java @@ -5,18 +5,13 @@ import org.junit.Before; import org.junit.Test; - - public class ConfigurationTest { - Configuration cfg = Configuration.getNewInstance(); - - - + @Before public void setUp() throws Exception { - + cfg.parse("struts.xml"); } @@ -27,29 +22,28 @@ 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"); + public void testGetResultView() { + String jsp = cfg.getResultView("login", "success"); Assert.assertEquals("/jsp/homepage.jsp", jsp); - - jsp = cfg.getResultView("login","fail"); + + jsp = cfg.getResultView("login", "fail"); Assert.assertEquals("/jsp/showLogin.jsp", jsp); - - jsp = cfg.getResultView("logout","success"); + + jsp = cfg.getResultView("logout", "success"); Assert.assertEquals("/jsp/welcome.jsp", jsp); - - jsp = cfg.getResultView("logout","error"); + + jsp = cfg.getResultView("logout", "error"); Assert.assertEquals("/jsp/error.jsp", jsp); - + } } diff --git a/group12/382266293/src/litestruts/Struts.java b/group12/382266293/src/litestruts/Struts.java index df9c4ed535..b84e2e6264 100644 --- a/group12/382266293/src/litestruts/Struts.java +++ b/group12/382266293/src/litestruts/Struts.java @@ -16,48 +16,46 @@ public class Struts { private static Object actionObj = null; private static String address = "src/litestruts/struts.xml"; private static ActionXMLreader reader = new ActionXMLreader(); - - @SuppressWarnings("unchecked") - public static View runAction(String actionName, Map parameters){ - - Node root = reader.getRootNode(address); - String clazz = reader.parseClass(root, actionName); - actionObj = getObj(clazz); - BeanInfo bi = getBeanInfo(actionObj); - PropertyDescriptor[] pd = bi.getPropertyDescriptors(); - - setParameters(actionObj, pd, parameters); - String executeResult = getResult(actionObj, bi, "execute"); - String jsp = reader.parseResult(root, actionName, executeResult); - Map readParamters = getReadParameters(actionObj, pd); - + + @SuppressWarnings("unchecked") + public static View runAction(String actionName, Map parameters) { + + Node root = reader.getRootNode(address); + String clazz = reader.parseClass(root, actionName); + actionObj = getObj(clazz); + BeanInfo bi = getBeanInfo(actionObj); + PropertyDescriptor[] pd = bi.getPropertyDescriptors(); + + setParameters(actionObj, pd, parameters); + String executeResult = getResult(actionObj, bi, "execute"); + String jsp = reader.parseResult(root, actionName, executeResult); + Map readParamters = getReadParameters(actionObj, pd); + View view = new View(); view.setJsp(jsp); view.setParameters(readParamters); - - return view; - } - + + return view; + } private static Object getObj(String clazz) { - @SuppressWarnings("rawtypes") + @SuppressWarnings("rawtypes") Class cls = null; - + try { cls = Class.forName(clazz); return cls.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); - }catch (InstantiationException | IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); - } + } return null; } + private static BeanInfo getBeanInfo(Object obj) { - private static BeanInfo getBeanInfo(Object obj) { - - BeanInfo bi = null; + BeanInfo bi = null; try { bi = Introspector.getBeanInfo(obj.getClass(), Object.class); } catch (IntrospectionException e) { @@ -65,51 +63,50 @@ private static BeanInfo getBeanInfo(Object obj) { } return bi; } - - private static void setParameters(Object obj, PropertyDescriptor[] pd ,Map parameters) { - - for (int i = 0; i < pd.length; i++) { - String name = pd[i].getName(); - if(parameters.containsKey(name)) - try { - pd[i].getWriteMethod().invoke(obj,parameters.get(name)); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - e.printStackTrace(); - } - } - } - - private static String getResult(Object obj, BeanInfo bi,String execute) { - MethodDescriptor[] methods = bi.getMethodDescriptors(); - for (int i = 0; i < methods.length; i++) { - String methodName = methods[i].getName(); - if(methodName.equals(execute)) + + private static void setParameters(Object obj, PropertyDescriptor[] pd, Map parameters) { + + for (int i = 0; i < pd.length; i++) { + String name = pd[i].getName(); + if (parameters.containsKey(name)) + try { + pd[i].getWriteMethod().invoke(obj, parameters.get(name)); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + + private static String getResult(Object obj, BeanInfo bi, String execute) { + MethodDescriptor[] methods = bi.getMethodDescriptors(); + for (int i = 0; i < methods.length; i++) { + String methodName = methods[i].getName(); + if (methodName.equals(execute)) try { return (String) methods[i].getMethod().invoke(actionObj); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } - } - return null; + } + return null; } - + @SuppressWarnings("rawtypes") - public static Map getReadParameters (Object obj, PropertyDescriptor[] pd) { + public static Map getReadParameters(Object obj, PropertyDescriptor[] pd) { - Map viewParams = new HashMap(); + Map viewParams = new HashMap(); - for (int i = 0; i < pd.length; i++) { - String readMethod = pd[i].getReadMethod().getName().substring(3); - String value = null; + for (int i = 0; i < pd.length; i++) { + String readMethod = pd[i].getReadMethod().getName().substring(3); + String value = null; try { value = (String) pd[i].getReadMethod().invoke(obj); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } - viewParams.put(readMethod.toLowerCase(), value); - } - return viewParams; - } - + viewParams.put(readMethod.toLowerCase(), value); + } + return viewParams; + } } \ No newline at end of file diff --git a/group12/382266293/src/litestruts/StrutsTest.java b/group12/382266293/src/litestruts/StrutsTest.java index 4b59f846f5..b450d7a935 100644 --- a/group12/382266293/src/litestruts/StrutsTest.java +++ b/group12/382266293/src/litestruts/StrutsTest.java @@ -6,38 +6,33 @@ import org.junit.Assert; import org.junit.Test; - - - - public class StrutsTest { @Test public void testLoginActionSuccess() { - + String actionName = "login"; - - Map params = new HashMap(); - params.put("name","test"); - params.put("password","1234"); - - - View view = Struts.runAction(actionName,params); - - Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); - Assert.assertEquals("login successful", view.getParameters().get("message")); + + Map params = new HashMap(); + params.put("name", "test"); + params.put("password", "1234"); + + View view = Struts.runAction(actionName, params); + + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); } @Test public void testLoginActionFailed() { String actionName = "login"; - Map params = new HashMap(); - params.put("name","test"); - params.put("password","123456"); //密码和预设的不一致 - - View view = Struts.runAction(actionName,params); - - Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); - Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + Map params = new HashMap(); + params.put("name", "test"); + params.put("password", "123456"); // 密码和预设的不一致 + + View view = Struts.runAction(actionName, params); + + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); } } diff --git a/group12/382266293/src/litestruts/View.java b/group12/382266293/src/litestruts/View.java index 5a7d948765..0c917dcb35 100644 --- a/group12/382266293/src/litestruts/View.java +++ b/group12/382266293/src/litestruts/View.java @@ -5,17 +5,20 @@ public class View { private String jsp; private Map parameters; - + public String getJsp() { return jsp; } + public View setJsp(String jsp) { this.jsp = jsp; return this; } + public Map getParameters() { return parameters; } + public View setParameters(Map parameters) { this.parameters = parameters; return this; diff --git a/group12/382266293/src/litestruts/struts.xml b/group12/382266293/src/litestruts/struts.xml index 4c6eeabbd4..1370971a4b 100644 --- a/group12/382266293/src/litestruts/struts.xml +++ b/group12/382266293/src/litestruts/struts.xml @@ -1,11 +1,11 @@ - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + \ No newline at end of file diff --git a/group12/382266293/src/test.java b/group12/382266293/src/test.java index a705772df2..b3a32d2556 100644 --- a/group12/382266293/src/test.java +++ b/group12/382266293/src/test.java @@ -10,24 +10,24 @@ public class test { - public static String url = "http://sw.bos.baidu.com/sw-search-sp/software/89179b0b248b1/QQ_8.9.20026.0_setup.exe"; + public static String url = "http://sw.bos.baidu.com/sw-search-sp/software/89179b0b248b1/QQ_8.9.20026.0_setup.exe"; public static String url2 = "http://image.beekka.com/blog/201304/bg2013042401.jpg"; public static String downloadLocation = "C:\\"; public static String tempName = ""; public static String fileName = ""; - + LinkedList a; - + private static void createTempFile1(String from) { long length = 0; URL url = null; HttpURLConnection conn = null; try { url = new URL(from); - conn = (HttpURLConnection)url.openConnection(); + conn = (HttpURLConnection) url.openConnection(); String file = conn.getURL().getFile(); - fileName = file.substring(file.lastIndexOf('/')+1); - tempName = fileName.substring(0, fileName.lastIndexOf('.')+1) + "lyj"; + fileName = file.substring(file.lastIndexOf('/') + 1); + tempName = fileName.substring(0, fileName.lastIndexOf('.') + 1) + "lyj"; length = conn.getContentLength(); conn.disconnect(); } catch (IOException e) { @@ -37,7 +37,7 @@ private static void createTempFile1(String from) { } tempName = downloadLocation + tempName; fileName = downloadLocation + fileName; - bufferFile(tempName,length); + bufferFile(tempName, length); } public static void bufferFile(String name, long len) { @@ -53,7 +53,7 @@ public static void bufferFile(String name, long len) { temp.write(buffer); } temp.write(buffer, 0, left); - + } catch (Exception e) { e.printStackTrace(); } finally { @@ -65,23 +65,22 @@ public static void bufferFile(String name, long len) { } } } - - + public static void download(String src) { createTempFile1(src); - + URL url = null; HttpURLConnection conn = null; FileOutputStream out = null; InputStream in = null; try { url = new URL(src); - conn = (HttpURLConnection)url.openConnection(); - in = conn.getInputStream(); + conn = (HttpURLConnection) url.openConnection(); + in = conn.getInputStream(); out = new FileOutputStream(tempName); byte[] buffer = new byte[1024]; int len = 0; - while( (len = in.read(buffer)) != -1) { + while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } conn.disconnect(); @@ -95,20 +94,19 @@ public static void download(String src) { } } - + public static boolean rename(String temp) { - File file=new File(temp); - File f1=new File(fileName); - if( file.exists() ) { + File file = new File(temp); + File f1 = new File(fileName); + if (file.exists()) { file.renameTo(f1); file = f1; - System.out.println("文件重命名为:"+f1.getName()); + System.out.println("文件重命名为:" + f1.getName()); return true; } return false; } - public static void main(String[] args) throws IOException { download(url2); diff --git a/group12/446031103/src/com/coderising/jvm/clz/AccessFlag.java b/group12/446031103/src/com/coderising/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..faae056835 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.coderising.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group12/446031103/src/com/coderising/jvm/clz/ClassFile.java b/group12/446031103/src/com/coderising/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..650ca8375d --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,75 @@ +package com.coderising.jvm.clz; + +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + + System.out.println("Super Class Name:"+ getSuperClassName()); + + + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group12/446031103/src/com/coderising/jvm/clz/ClassIndex.java b/group12/446031103/src/com/coderising/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..e424f284b3 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package com.coderising.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group12/446031103/src/com/coderising/jvm/constant/ClassInfo.java b/group12/446031103/src/com/coderising/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..aea9048ea4 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package com.coderising.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index ; + public ClassInfo(ConstantPool pool) { + super(pool); + } + public int getUtf8Index() { + return utf8Index; + } + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group12/446031103/src/com/coderising/jvm/constant/ConstantInfo.java b/group12/446031103/src/com/coderising/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..466b072244 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group12/446031103/src/com/coderising/jvm/constant/ConstantPool.java b/group12/446031103/src/com/coderising/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..86c0445695 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group12/446031103/src/com/coderising/jvm/constant/FieldRefInfo.java b/group12/446031103/src/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..65475e194c --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group12/446031103/src/com/coderising/jvm/constant/MethodRefInfo.java b/group12/446031103/src/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..7f05870020 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group12/446031103/src/com/coderising/jvm/constant/NameAndTypeInfo.java b/group12/446031103/src/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..402f9dec86 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group12/446031103/src/com/coderising/jvm/constant/NullConstantInfo.java b/group12/446031103/src/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..936736016f --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group12/446031103/src/com/coderising/jvm/constant/StringInfo.java b/group12/446031103/src/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..f1f8eb4ed4 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index; + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group12/446031103/src/com/coderising/jvm/constant/UTF8Info.java b/group12/446031103/src/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..5cac9f04f7 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group12/446031103/src/com/coderising/jvm/loader/ByteCodeIterator.java b/group12/446031103/src/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..9c9fac2839 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,5 @@ +package com.coderising.jvm.loader; + +public class ByteCodeIterator { + +} diff --git a/group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java b/group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java index e021b94d38..33185d8175 100644 --- a/group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java +++ b/group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -1,8 +1,20 @@ package com.coderising.jvm.loader; +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +import com.coderising.jvm.clz.ClassFile; + + + public class ClassFileLoader { @@ -11,33 +23,118 @@ public class ClassFileLoader { public byte[] readBinaryCode(String className) { - return null; + className = className.replace('.', File.separatorChar) +".class"; + + for(String path : this.clzPaths){ + + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if(codes != null){ + return codes; + } + } + + return null; + } private byte[] loadClassFile(String clzFileName) { - return null; + File f = new File(clzFileName); + + try { + + return IOUtils.toByteArray(new FileInputStream(f)); + + } catch (IOException e) { + e.printStackTrace(); + return null; + } } public void addClassPath(String path) { + if(this.clzPaths.contains(path)){ + return; + } + + this.clzPaths.add(path); } - public String getClassPath_V1(){ + + + public String getClassPath(){ + return StringUtils.join(this.clzPaths,";"); + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); - return null; } - public String getClassPath(){ + + + // ------------------------------backup------------------------ + public String getClassPath_V1(){ + + StringBuffer buffer = new StringBuffer(); + for(int i=0;i", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + } diff --git a/group12/446031103/src/com/coderising/jvm/test/EmployeeV1.java b/group12/446031103/src/com/coderising/jvm/test/EmployeeV1.java index 5e2bd8668f..12e3d7efdd 100644 --- a/group12/446031103/src/com/coderising/jvm/test/EmployeeV1.java +++ b/group12/446031103/src/com/coderising/jvm/test/EmployeeV1.java @@ -25,4 +25,4 @@ public static void main(String[] args){ p.sayHello(); } -} +} \ No newline at end of file diff --git a/group12/446031103/src/com/coderising/jvm/util/Util.java b/group12/446031103/src/com/coderising/jvm/util/Util.java new file mode 100644 index 0000000000..0c4cc8c57c --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/util/Util.java @@ -0,0 +1,24 @@ +package com.coderising.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes){ + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i= capacity) { + removeLast(); + + } + + addNewNodetoHead(node); + + + + + } + } + + private void addNewNodetoHead(Node node) { + + if(isEmpty()){ + + node.prev = null; + node.next = null; + first = node; + last = node; + + } else{ + node.prev = null; + node.next = first; + first.prev = node; + first = node; + } + this.currentSize ++; + } + + private Node find(int data){ + + Node node = first; + while(node != null){ + if(node.pageNum == data){ + return node; + } + node = node.next; + } + return null; + + } + + + + + + + /** + * 删除链表尾部节点 表示 删除最少使用的缓存对象 + */ + private void removeLast() { + Node prev = last.prev; + prev.next = null; + last.prev = null; + last = prev; + this.currentSize --; + } + + /** + * 移动到链表头,表示这个节点是最新使用过的 + * + * @param node + */ + private void moveExistingNodeToHead(Node node) { + + if (node == first) { + + return; + } + else if(node == last){ + //当前节点是链表尾, 需要放到链表头 + Node prevNode = node.prev; + prevNode.next = null; + last.prev = null; + last = prevNode; + + } else{ + //node 在链表的中间, 把node 的前后节点连接起来 + Node prevNode = node.prev; + prevNode.next = node.next; + + Node nextNode = node.next; + nextNode.prev = prevNode; + + + } + + node.prev = null; + node.next = first; + first.prev = node; + first = node; + + } + private boolean isEmpty(){ + return (first == null) && (last == null); + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + + /*private static class Node { Node prev; Node next; @@ -38,12 +194,12 @@ public LRUPageFrame(int capacity) { first = new Node(); } - /** + *//** * 获取缓存中对象 * * @param key * @return - */ + *//* public void access(int pageNum) { if(null==this.last){ this.last = new Node(this.first,null,pageNum); @@ -153,6 +309,6 @@ public String toString(){ } } return buffer.toString(); - } + }*/ } \ No newline at end of file diff --git a/group12/446031103/src/com/datastructure/stack/Stack.java b/group12/446031103/src/com/datastructure/stack/Stack.java new file mode 100644 index 0000000000..82cdf178a6 --- /dev/null +++ b/group12/446031103/src/com/datastructure/stack/Stack.java @@ -0,0 +1,83 @@ +package com.datastructure.stack; + +import com.datastructure.array.ArrayList; + +/** + * + * 栈-先进后出 + * + * @ClassName Stack + * @author msh + * @date 2017年2月21日 下午9:05:39 + */ +public class Stack { + + private ArrayList elementData = new ArrayList(); + /** + * + * 向栈中加入元素 + * + * @MethodName push + * @author msh + * @date 2017年2月21日 下午9:12:03 + * @param o + */ + public void push(Object o){ + elementData.add(o); + } + /** + * + * 从栈中取出元素 + * + * @MethodName pop + * @author msh + * @date 2017年2月21日 下午9:12:51 + * @return + */ + public Object pop(){ + Object o= peek(); + elementData.remove(size()-1); + return o; + } + /** + * + * 取出栈顶元素 + * + * @MethodName peek + * @author msh + * @date 2017年2月21日 下午9:13:08 + * @return + */ + public Object peek(){ + Object o=elementData.get(size()-1); + return o; + } + /** + * + * 判断栈中是否有元素 + * + * @MethodName isEmpty + * @author msh + * @date 2017年2月21日 下午9:14:26 + * @return + */ + public boolean isEmpty(){ + boolean temp = false; + if(0==size()) + temp = true; + return temp; + } + /** + * + * 栈中有多少元素 + * + * @MethodName size + * @author msh + * @date 2017年2月21日 下午9:16:42 + * @return + */ + public int size(){ + return elementData.size(); + } + +} diff --git a/group12/446031103/src/com/datastructure/stack/StackUtil.java b/group12/446031103/src/com/datastructure/stack/StackUtil.java new file mode 100644 index 0000000000..7cab99ede3 --- /dev/null +++ b/group12/446031103/src/com/datastructure/stack/StackUtil.java @@ -0,0 +1,107 @@ +package com.datastructure.stack; +import java.util.Objects; +import java.util.Stack; + +public class StackUtil { + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + Stack temp = new Stack(); + while(!s.isEmpty()){ + temp.push(s.pop()); + } + s = temp; + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + Stack temp = new Stack(); + while(!s.isEmpty()){ + Object result=s.pop(); + if(Objects.equals(result, o)){ + continue; + } + temp.push(result); + } + while(!temp.isEmpty()){ + s.push(temp.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + Object [] obj= new Object[len] ; + Stack temp = new Stack(); + for (int i = 0; i s.size()) { + Object[] arr = new Object[s.size()]; + int i = 0; + while (!s.isEmpty()) { + arr[i] = s.pop(); + i++; + } + for (int j = 0; j < arr.length; j++) { + s.push(arr[j]); + } + return arr; + } else { + Object[] arr = new Object[len]; + int i = 0; + while (!s.isEmpty()) { + arr[i] = s.pop(); + i++; + } + for (int j = 0; j < arr.length; j++) { + s.push(arr[j]); + } + return arr; + } + } + + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + char[] arr = s.toCharArray(); + Stack st1 = new Stack(); + Stack st2 = new Stack(); + for (int i = 0; i < arr.length; i++) { + st1.push(arr[i]); + } + for (int i = arr.length - 1; i >= 0; i--) { + st2.push(arr[i]); + } + + while (!st1.isEmpty()) { + + char ch1 = (char) st1.pop(); + char ch2 = (char) st2.pop(); + switch (ch1) { + case '{': + if (ch2 != '}') { + return false; + } + break; + case '[': + if (ch2 != ']') { + return false; + } + break; + case '(': + if (ch2 != ')') { + return false; + } + break; + } + } + + return true; + } + + +} \ No newline at end of file diff --git a/group13/2729382520/L5/jvm/clz/AccessFlag.java b/group13/2729382520/L5/jvm/clz/AccessFlag.java new file mode 100755 index 0000000000..4c3a3c8900 --- /dev/null +++ b/group13/2729382520/L5/jvm/clz/AccessFlag.java @@ -0,0 +1,26 @@ +package io.github.vxzh.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass() { + return (this.flagValue & 0x0001) != 0; + } + + public boolean isFinalClass() { + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group13/2729382520/L5/jvm/clz/ClassFile.java b/group13/2729382520/L5/jvm/clz/ClassFile.java new file mode 100755 index 0000000000..1d7011545b --- /dev/null +++ b/group13/2729382520/L5/jvm/clz/ClassFile.java @@ -0,0 +1,80 @@ +package io.github.vxzh.jvm.clz; + +import io.github.vxzh.jvm.constant.ClassInfo; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + + public ClassIndex getClzIndex() { + return clzIndex; + } + + public AccessFlag getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + public ConstantPool getConstantPool() { + return pool; + } + + public int getMinorVersion() { + return minorVersion; + } + + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + + public int getMajorVersion() { + return majorVersion; + } + + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + public void print() { + + if (this.accessFlag.isPublicClass()) { + System.out.println("Access flag : public "); + } + System.out.println("Class Name:" + getClassName()); + + System.out.println("Super Class Name:" + getSuperClassName()); + + + } + + private String getClassName() { + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo) this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + + private String getSuperClassName() { + ClassInfo superClass = (ClassInfo) this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group13/2729382520/L5/jvm/clz/ClassIndex.java b/group13/2729382520/L5/jvm/clz/ClassIndex.java new file mode 100755 index 0000000000..4500959430 --- /dev/null +++ b/group13/2729382520/L5/jvm/clz/ClassIndex.java @@ -0,0 +1,22 @@ +package io.github.vxzh.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + + public int getSuperClassIndex() { + return superClassIndex; + } + + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group13/2729382520/L5/jvm/clz/ConstantPool.java b/group13/2729382520/L5/jvm/clz/ConstantPool.java new file mode 100755 index 0000000000..b96e330020 --- /dev/null +++ b/group13/2729382520/L5/jvm/clz/ConstantPool.java @@ -0,0 +1,35 @@ +package io.github.vxzh.jvm.clz; + +import io.github.vxzh.jvm.constant.ConstantInfo; +import io.github.vxzh.jvm.constant.UTF8Info; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool() { + + } + + public void addConstantInfo(ConstantInfo info) { + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantInfos.get(index); + } + + public String getUTF8String(int index) { + return ((UTF8Info) this.constantInfos.get(index)).getValue(); + } + + public Object getSize() { + return this.constantInfos.size() - 1; + } +} diff --git a/group13/2729382520/L5/jvm/constant/ClassInfo.java b/group13/2729382520/L5/jvm/constant/ClassInfo.java new file mode 100755 index 0000000000..c9586ee16c --- /dev/null +++ b/group13/2729382520/L5/jvm/constant/ClassInfo.java @@ -0,0 +1,30 @@ +package io.github.vxzh.jvm.constant; + +import io.github.vxzh.jvm.clz.ConstantPool; + +public class ClassInfo extends ConstantInfo { + private int tag = ConstantInfo.CONSTANT_CLASS_INFO; + private int nameIndex; + + public ClassInfo(ConstantPool pool) { + super(pool); + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getTag() { + return tag; + } + + public String getClassName() { + int index = getNameIndex(); + UTF8Info utf8Info = (UTF8Info) constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group13/2729382520/L5/jvm/constant/ConstantInfo.java b/group13/2729382520/L5/jvm/constant/ConstantInfo.java new file mode 100755 index 0000000000..0f3d63685c --- /dev/null +++ b/group13/2729382520/L5/jvm/constant/ConstantInfo.java @@ -0,0 +1,42 @@ +package io.github.vxzh.jvm.constant; + +import io.github.vxzh.jvm.clz.ConstantPool; + +public abstract class ConstantInfo { + + public static final int CONSTANT_UTF8_INFO = 1;// + public static final int CONSTANT_INTEGER_INFO = 3; + public static final int CONSTANT_FLOAT_INFO = 4;// + public static final int CONSTANT_LONG_INFO = 5; + public static final int CONSTANT_DOUBLE_INFO = 6; + public static final int CONSTANT_CLASS_INFO = 7;// + public static final int CONSTANT_STRING_INFO = 8;// + public static final int CONSTANT_FIELDREF_INFO = 9;// + public static final int CONSTANT_METHODREF_INFO = 10;// + public static final int CONSTANT_INTERFACEMETHODREF_INFO = 11; + public static final int CONSTANT_NAMEANDTYPE_INFO = 12;// + public static final int CONSTANT_METHODHANDLE_INFO = 15; + public static final int CONSTANT_METHODTYPE_INFO = 16; + public static final int CONSTANT_INVOKEDYNAMIC_INFO = 18; + + protected ConstantPool constantPool; + + public ConstantInfo() { + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + + public abstract int getTag(); + + public ConstantPool getConstantPool() { + return constantPool; + } + + public ConstantInfo getConstantInfo(int index) { + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group13/2729382520/L5/jvm/constant/FieldRefInfo.java b/group13/2729382520/L5/jvm/constant/FieldRefInfo.java new file mode 100755 index 0000000000..f39bc87b72 --- /dev/null +++ b/group13/2729382520/L5/jvm/constant/FieldRefInfo.java @@ -0,0 +1,60 @@ +package io.github.vxzh.jvm.constant; + +import io.github.vxzh.jvm.clz.ConstantPool; + +public class FieldRefInfo extends ConstantInfo { + private int tag = ConstantInfo.CONSTANT_FIELDREF_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + + public int getTag() { + return tag; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() + " : " + typeInfo.getName() + ":" + typeInfo.getTypeInfo() + "]"; + } + + public String getClassName() { + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info) this.getConstantInfo(classInfo.getNameIndex()); + + return utf8Info.getValue(); + + } + + public String getFieldName() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType() { + NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group13/2729382520/L5/jvm/constant/MethodRefInfo.java b/group13/2729382520/L5/jvm/constant/MethodRefInfo.java new file mode 100755 index 0000000000..46535b7769 --- /dev/null +++ b/group13/2729382520/L5/jvm/constant/MethodRefInfo.java @@ -0,0 +1,60 @@ +package io.github.vxzh.jvm.constant; + +import io.github.vxzh.jvm.clz.ConstantPool; + +public class MethodRefInfo extends ConstantInfo { + + private int tag = ConstantInfo.CONSTANT_METHODREF_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getTag() { + return tag; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString() { + + return getClassName() + " : " + this.getMethodName() + " : " + this.getParamAndReturnType(); + } + + public String getClassName() { + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo) pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType() { + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo) pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + +} diff --git a/group13/2729382520/L5/jvm/constant/NameAndTypeInfo.java b/group13/2729382520/L5/jvm/constant/NameAndTypeInfo.java new file mode 100755 index 0000000000..a081902eac --- /dev/null +++ b/group13/2729382520/L5/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,51 @@ +package io.github.vxzh.jvm.constant; + +import io.github.vxzh.jvm.clz.ConstantPool; + +public class NameAndTypeInfo extends ConstantInfo { + public int tag = ConstantInfo.CONSTANT_NAMEANDTYPE_INFO; + + private int nameIndex; + private int descriptorIndex; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public void setDescriptorIndex(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } + + public int getTag() { + return tag; + } + + + public String getName() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info) pool.getConstantInfo(nameIndex); + return utf8Info1.getValue(); + } + + public String getTypeInfo() { + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info) pool.getConstantInfo(descriptorIndex); + return utf8Info2.getValue(); + } + + public String toString() { + return "(" + getName() + "," + getTypeInfo() + ")"; + } +} diff --git a/group13/2729382520/L5/jvm/constant/NullConstantInfo.java b/group13/2729382520/L5/jvm/constant/NullConstantInfo.java new file mode 100755 index 0000000000..1d1d8394f9 --- /dev/null +++ b/group13/2729382520/L5/jvm/constant/NullConstantInfo.java @@ -0,0 +1,14 @@ +package io.github.vxzh.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo() { + + } + + @Override + public int getTag() { + return -1; + } + +} diff --git a/group13/2729382520/L5/jvm/constant/StringInfo.java b/group13/2729382520/L5/jvm/constant/StringInfo.java new file mode 100755 index 0000000000..e5175eed4a --- /dev/null +++ b/group13/2729382520/L5/jvm/constant/StringInfo.java @@ -0,0 +1,30 @@ +package io.github.vxzh.jvm.constant; + +import io.github.vxzh.jvm.clz.ConstantPool; + +public class StringInfo extends ConstantInfo { + private int tag = ConstantInfo.CONSTANT_STRING_INFO; + private int index; + + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getTag() { + return tag; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + + public String toString() { + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group13/2729382520/L5/jvm/constant/UTF8Info.java b/group13/2729382520/L5/jvm/constant/UTF8Info.java new file mode 100755 index 0000000000..e1fb81006b --- /dev/null +++ b/group13/2729382520/L5/jvm/constant/UTF8Info.java @@ -0,0 +1,40 @@ +package io.github.vxzh.jvm.constant; + +import io.github.vxzh.jvm.clz.ConstantPool; + +public class UTF8Info extends ConstantInfo { + private int tag = ConstantInfo.CONSTANT_UTF8_INFO; + private int length; + private String value; + + public UTF8Info(ConstantPool pool) { + super(pool); + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getTag() { + return tag; + } + + @Override + public String toString() { + return "UTF8Info [tag=" + tag + ", length=" + length + ", value=" + value + ")]"; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + +} diff --git a/group13/2729382520/L5/jvm/loader/ByteCodeIterator.java b/group13/2729382520/L5/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..2b3fd9b896 --- /dev/null +++ b/group13/2729382520/L5/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,41 @@ +package io.github.vxzh.jvm.loader; + +import io.github.vxzh.jvm.util.Util; + +import java.util.Arrays; + +public class ByteCodeIterator { + private int pos = 0; + private byte[] code; + + public ByteCodeIterator(byte[] code) { + this.code = code; + } + + public String nextU4ToHexString() { + byte[] bytes = nextBytes(4); + return Util.byteToHexString(bytes); + } + + public int nextU2ToInt() { + byte[] bytes = nextBytes(2); + return Util.byteToInt(bytes); + } + + public int nextU1ToInt() { + byte[] bytes = nextBytes(1); + return Util.byteToInt(bytes); + } + + public String nextBytesToString(int len) { + byte[] bytes = nextBytes(len); + return new String(bytes); + } + + private byte[] nextBytes(int len) { + byte[] bytes = Arrays.copyOfRange(code, pos, pos+len); + pos += len; + return bytes; + } + +} \ No newline at end of file diff --git a/group13/2729382520/L5/jvm/loader/ClassFileLoader.java b/group13/2729382520/L5/jvm/loader/ClassFileLoader.java new file mode 100755 index 0000000000..c10a6ad295 --- /dev/null +++ b/group13/2729382520/L5/jvm/loader/ClassFileLoader.java @@ -0,0 +1,108 @@ +package io.github.vxzh.jvm.loader; + +import io.github.vxzh.jvm.clz.ClassFile; +import org.apache.commons.io.IOUtils; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + + +public class ClassFileLoader { + + private static final int BUFFER_MAX_SIZE = 1024; + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + className = className.replaceAll("\\.", "/"); + File file = findFile(className); + if (file == null) { + return new byte[0]; + } + + FileInputStream fis = null; + ByteArrayOutputStream bos = null; + try { + fis = new FileInputStream(file); + bos = new ByteArrayOutputStream(); + byte buffer[] = new byte[BUFFER_MAX_SIZE]; + int len = -1; + while ((len = fis.read(buffer)) != -1) { + bos.write(buffer, 0, len); + } + return bos.toByteArray(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (fis != null) + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + if (bos != null) + bos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return null; + } + + public void addClassPath(String path) { + if (this.clzPaths.contains(path)) { + return; + } + clzPaths.add(path); + } + + public String getClassPath() { + + StringBuilder builder = new StringBuilder(); + for (String path : clzPaths) { + builder.append(path).append(";"); + } + + return builder.toString().substring(0, builder.toString().length() - 1); + } + + private File findFile(String className) { + for (String path : clzPaths) { + String filePath = path + "/" + className + ".class"; + File file = new File(filePath); + if (file.exists()) { + return file; + } + } + return null; + } + + private byte[] loadClassFile(String clzFileName) { + + File f = new File(clzFileName); + + try { + + return IOUtils.toByteArray(new FileInputStream(f)); + + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + + +} \ No newline at end of file diff --git a/group13/2729382520/L5/jvm/loader/ClassFileParser.java b/group13/2729382520/L5/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..378d1b68e8 --- /dev/null +++ b/group13/2729382520/L5/jvm/loader/ClassFileParser.java @@ -0,0 +1,99 @@ +package io.github.vxzh.jvm.loader; + +import io.github.vxzh.jvm.clz.AccessFlag; +import io.github.vxzh.jvm.clz.ClassFile; +import io.github.vxzh.jvm.clz.ClassIndex; +import io.github.vxzh.jvm.clz.ConstantPool; +import io.github.vxzh.jvm.constant.*; + + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + + ByteCodeIterator byteCodeIterator = new ByteCodeIterator(codes); + String magicNumber = byteCodeIterator.nextU4ToHexString(); + if (!"cafebabe".equals(magicNumber)) + throw new RuntimeException("This is not a Java Class file!"); + + ClassFile classFile = new ClassFile(); + int minorVersion = byteCodeIterator.nextU2ToInt(); + classFile.setMinorVersion(minorVersion); + int majorVersion = byteCodeIterator.nextU2ToInt(); + classFile.setMajorVersion(majorVersion); + + classFile.setConstPool(this.parseConstantPool(byteCodeIterator)); + classFile.setAccessFlag(this.parseAccessFlag(byteCodeIterator)); + classFile.setClassIndex(this.parseClassInfex(byteCodeIterator)); + + return classFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iterator) { + return new AccessFlag(iterator.nextU2ToInt()); + } + + private ClassIndex parseClassInfex(ByteCodeIterator iterator) { + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(iterator.nextU2ToInt()); + classIndex.setSuperClassIndex(iterator.nextU2ToInt()); + return classIndex; + } + + private ConstantPool parseConstantPool(ByteCodeIterator iterator) { + + int constantCount = iterator.nextU2ToInt(); + ConstantPool constantPool = new ConstantPool(); + constantPool.addConstantInfo(new NullConstantInfo()); + for (int i = 0; i < constantCount; i++) { + int tag = iterator.nextU1ToInt(); + switch (tag) { + case ConstantInfo.CONSTANT_CLASS_INFO: + ClassInfo classInfo = new ClassInfo(constantPool); + classInfo.setNameIndex(iterator.nextU2ToInt()); + constantPool.addConstantInfo(classInfo); + System.out.println("classInfo " + classInfo.getNameIndex()); + break; + case ConstantInfo.CONSTANT_UTF8_INFO: + UTF8Info utf8Info = new UTF8Info(constantPool); + utf8Info.setLength(iterator.nextU2ToInt()); + utf8Info.setValue(iterator.nextBytesToString(utf8Info.getLength())); + constantPool.addConstantInfo(utf8Info); + System.out.println("utf-8 " + utf8Info.getValue()); + break; + case ConstantInfo.CONSTANT_METHODREF_INFO: + MethodRefInfo methodRefInfo = new MethodRefInfo(constantPool); + methodRefInfo.setClassInfoIndex(iterator.nextU2ToInt()); + methodRefInfo.setNameAndTypeIndex(iterator.nextU2ToInt()); + constantPool.addConstantInfo(methodRefInfo); + System.out.println("method ref " + methodRefInfo.getClassInfoIndex() + " " + methodRefInfo.getNameAndTypeIndex()); + break; + case ConstantInfo.CONSTANT_NAMEANDTYPE_INFO: + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(constantPool); + nameAndTypeInfo.setNameIndex(iterator.nextU2ToInt()); + nameAndTypeInfo.setDescriptorIndex(iterator.nextU2ToInt()); + constantPool.addConstantInfo(nameAndTypeInfo); + System.out.println("name and type " + nameAndTypeInfo.getNameIndex() + " " + nameAndTypeInfo.getDescriptorIndex()); + break; + case ConstantInfo.CONSTANT_FIELDREF_INFO: + FieldRefInfo fieldRefInfo = new FieldRefInfo(constantPool); + fieldRefInfo.setClassInfoIndex(iterator.nextU2ToInt()); + fieldRefInfo.setNameAndTypeIndex(iterator.nextU2ToInt()); + constantPool.addConstantInfo(fieldRefInfo); + System.out.println("field ref " + fieldRefInfo.getClassInfoIndex() + " " + fieldRefInfo.getNameAndTypeIndex()); + break; + case ConstantInfo.CONSTANT_STRING_INFO: + StringInfo stringInfo = new StringInfo(constantPool); + stringInfo.setIndex(iterator.nextU2ToInt()); + constantPool.addConstantInfo(stringInfo); + System.out.println("string " + stringInfo.getIndex()); + break; + default: + //throw new RuntimeException("the constant Pool tag "+tag+" has not been implement yet!"); + } + } + return constantPool; + } + + +} diff --git a/group13/2729382520/L5/jvm/test/ClassFileloaderTest.java b/group13/2729382520/L5/jvm/test/ClassFileloaderTest.java new file mode 100755 index 0000000000..9223e0f7ad --- /dev/null +++ b/group13/2729382520/L5/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,188 @@ +package io.github.vxzh.jvm.test; + +import io.github.vxzh.jvm.clz.ClassFile; +import io.github.vxzh.jvm.clz.ClassIndex; +import io.github.vxzh.jvm.clz.ConstantPool; +import io.github.vxzh.jvm.constant.*; +import io.github.vxzh.jvm.loader.ClassFileLoader; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ClassFileloaderTest { + + + private static final String FULL_QUALIFIED_CLASS_NAME = "io/github/vxzh/jvm/test/EmployeeV1.java"; + static String path1 = "/Users/xuxiaoqing/Workspace/test"; + static String path2 = "/Users/xuxiaoqing/Documents/demo"; + + static ClassFile clzFile = null; + + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "io.github.vxzh.jvm.test.EmployeeV1"; + + clzFile = loader.loadClass(className); + //clzFile.print(); + } + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1 + ";" + path2, clzPath); + + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "io.github.vxzh.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1056, byteCodes.length); + + } + + + @Test + public void testMagicNumber() { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "io.github.vxzh.jvm.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + private String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + + @Test + public void testVersion() { + + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool() { + + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getNameIndex()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getNameIndex()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo) pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getNameIndex()); + Assert.assertEquals(14, nameAndType.getDescriptorIndex()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo) pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + + @Test + public void testClassIndex() { + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo) clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo) clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + +} \ No newline at end of file diff --git a/group13/2729382520/L5/jvm/test/EmployeeV1.java b/group13/2729382520/L5/jvm/test/EmployeeV1.java new file mode 100755 index 0000000000..87e05ff033 --- /dev/null +++ b/group13/2729382520/L5/jvm/test/EmployeeV1.java @@ -0,0 +1,29 @@ +package io.github.vxzh.jvm.test; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + } +} \ No newline at end of file diff --git a/group13/2729382520/L5/jvm/util/Util.java b/group13/2729382520/L5/jvm/util/Util.java new file mode 100644 index 0000000000..9a659ef3eb --- /dev/null +++ b/group13/2729382520/L5/jvm/util/Util.java @@ -0,0 +1,23 @@ +package io.github.vxzh.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes) { + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + public static String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} \ No newline at end of file diff --git a/group13/2931408816/.gradle/3.1/taskArtifacts/cache.properties.lock b/group13/2931408816/.gradle/3.1/taskArtifacts/cache.properties.lock index e526851619..3c3d84d35b 100644 Binary files a/group13/2931408816/.gradle/3.1/taskArtifacts/cache.properties.lock and b/group13/2931408816/.gradle/3.1/taskArtifacts/cache.properties.lock differ diff --git a/group13/2931408816/.gradle/3.1/taskArtifacts/fileHashes.bin b/group13/2931408816/.gradle/3.1/taskArtifacts/fileHashes.bin index df74348046..12cab10b96 100644 Binary files a/group13/2931408816/.gradle/3.1/taskArtifacts/fileHashes.bin and b/group13/2931408816/.gradle/3.1/taskArtifacts/fileHashes.bin differ diff --git a/group13/2931408816/.gradle/3.1/taskArtifacts/fileSnapshots.bin b/group13/2931408816/.gradle/3.1/taskArtifacts/fileSnapshots.bin index d65e698bbc..09cd2629f8 100644 Binary files a/group13/2931408816/.gradle/3.1/taskArtifacts/fileSnapshots.bin and b/group13/2931408816/.gradle/3.1/taskArtifacts/fileSnapshots.bin differ diff --git a/group13/2931408816/.gradle/3.1/taskArtifacts/taskArtifacts.bin b/group13/2931408816/.gradle/3.1/taskArtifacts/taskArtifacts.bin index 69a7010d72..3c70119c9f 100644 Binary files a/group13/2931408816/.gradle/3.1/taskArtifacts/taskArtifacts.bin and b/group13/2931408816/.gradle/3.1/taskArtifacts/taskArtifacts.bin differ diff --git a/group13/2931408816/.idea/compiler.xml b/group13/2931408816/.idea/compiler.xml index 3d1b215f42..602f0772b0 100644 --- a/group13/2931408816/.idea/compiler.xml +++ b/group13/2931408816/.idea/compiler.xml @@ -10,6 +10,10 @@ + + + + \ No newline at end of file diff --git a/group13/2931408816/.idea/gradle.xml b/group13/2931408816/.idea/gradle.xml index 4a7350459a..246a806334 100644 --- a/group13/2931408816/.idea/gradle.xml +++ b/group13/2931408816/.idea/gradle.xml @@ -13,6 +13,8 @@ diff --git a/group13/2931408816/.idea/modules.xml b/group13/2931408816/.idea/modules.xml index b8bbae7f40..762aea64c1 100644 --- a/group13/2931408816/.idea/modules.xml +++ b/group13/2931408816/.idea/modules.xml @@ -3,7 +3,7 @@ - + @@ -12,9 +12,16 @@ - + + + + + + + + \ No newline at end of file diff --git a/group13/2931408816/.idea/workspace.xml b/group13/2931408816/.idea/workspace.xml index 5491e4d0a1..38a332457d 100644 --- a/group13/2931408816/.idea/workspace.xml +++ b/group13/2931408816/.idea/workspace.xml @@ -11,6 +11,10 @@ + + + + - -