From d6191439eca542c7a1d25175af0af331b62e74fb Mon Sep 17 00:00:00 2001 From: thomas_young Date: Sat, 6 May 2017 17:42:21 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E6=89=93=E5=8D=B0constantInfo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coderising/jvm/constant/ClassInfo.java | 7 ++ .../coderising/jvm/constant/ConstantInfo.java | 4 +- .../coderising/jvm/constant/ConstantPool.java | 2 +- .../coderising/jvm/constant/FieldRefInfo.java | 7 ++ .../jvm/constant/MethodRefInfo.java | 8 +- .../jvm/constant/NameAndTypeInfo.java | 7 ++ .../jvm/constant/NullConstantInfo.java | 8 +- .../coderising/jvm/constant/StringInfo.java | 8 +- .../coderising/jvm/constant/UTF8Info.java | 6 ++ .../jvm/print/ClassFilePrinter.java | 8 +- .../jvm/print/ConstantPoolPrinter.java | 74 ++++++++++++++++++- .../coderising/jvm/print/Visitable.java | 8 ++ 12 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/Visitable.java diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ClassInfo.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ClassInfo.java index e818dcb72b..3362189635 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ClassInfo.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ClassInfo.java @@ -1,5 +1,7 @@ package com.github.miniyk2012.coding2017.coderising.jvm.constant; +import com.github.miniyk2012.coding2017.coderising.jvm.print.ConstantPoolPrinter; + public class ClassInfo extends ConstantInfo { private int type = ConstantInfo.CLASS_INFO; private int utf8Index ; @@ -21,4 +23,9 @@ public String getClassName() { UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); return utf8Info.getValue(); } + + @Override + public void accept(ConstantPoolPrinter.Visitor visitor) { + visitor.visitClassInfo(this); + } } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ConstantInfo.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ConstantInfo.java index 3ec050d100..87f35f75e7 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ConstantInfo.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ConstantInfo.java @@ -1,6 +1,8 @@ package com.github.miniyk2012.coding2017.coderising.jvm.constant; -public abstract class ConstantInfo { +import com.github.miniyk2012.coding2017.coderising.jvm.print.Visitable; + +public abstract class ConstantInfo implements Visitable{ public static final int UTF8_INFO = 1; public static final int FLOAT_INFO = 4; public static final int CLASS_INFO = 7; diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ConstantPool.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ConstantPool.java index 09370db1e5..270979faae 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ConstantPool.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/ConstantPool.java @@ -25,7 +25,7 @@ public ConstantInfo getConstantInfo(int index){ public String getUTF8String(int index){ return ((UTF8Info)this.constantInfos.get(index)).getValue(); } - public Object getSize() { + public int getSize() { return this.constantInfos.size() -1; } } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/FieldRefInfo.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/FieldRefInfo.java index b69e5aebc6..c083d06e61 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/FieldRefInfo.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/FieldRefInfo.java @@ -1,5 +1,7 @@ package com.github.miniyk2012.coding2017.coderising.jvm.constant; +import com.github.miniyk2012.coding2017.coderising.jvm.print.ConstantPoolPrinter; + public class FieldRefInfo extends ConstantInfo{ private int type = ConstantInfo.FIELD_INFO; private int classInfoIndex; @@ -47,4 +49,9 @@ public String getFieldType(){ NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); return typeInfo.getTypeInfo(); } + + @Override + public void accept(ConstantPoolPrinter.Visitor visitor) { + visitor.visitFieldRefInfo(this); + } } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/MethodRefInfo.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/MethodRefInfo.java index a3cf910c99..c42caf3678 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/MethodRefInfo.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/MethodRefInfo.java @@ -1,5 +1,7 @@ package com.github.miniyk2012.coding2017.coderising.jvm.constant; +import com.github.miniyk2012.coding2017.coderising.jvm.print.ConstantPoolPrinter; + public class MethodRefInfo extends ConstantInfo { private int type = ConstantInfo.METHOD_INFO; @@ -52,5 +54,9 @@ public String getParamAndReturnType(){ NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(nameAndTypeIndex); return typeInfo.getTypeInfo(); } - + + @Override + public void accept(ConstantPoolPrinter.Visitor visitor) { + visitor.visitMethodRefInfo(this); + } } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/NameAndTypeInfo.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/NameAndTypeInfo.java index 79f421bdd1..83a4c7bb4b 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/NameAndTypeInfo.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/NameAndTypeInfo.java @@ -1,5 +1,7 @@ package com.github.miniyk2012.coding2017.coderising.jvm.constant; +import com.github.miniyk2012.coding2017.coderising.jvm.print.ConstantPoolPrinter; + public class NameAndTypeInfo extends ConstantInfo{ public int type = ConstantInfo.NAME_AND_TYPE_INFO; @@ -44,4 +46,9 @@ public String getTypeInfo(){ public String toString(){ return "(" + getName() + "," + getTypeInfo()+")"; } + + @Override + public void accept(ConstantPoolPrinter.Visitor visitor) { + visitor.visitNameAndTypeInfo(this); + } } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/NullConstantInfo.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/NullConstantInfo.java index 2a16601a40..5bcb981a9c 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/NullConstantInfo.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/NullConstantInfo.java @@ -1,5 +1,7 @@ package com.github.miniyk2012.coding2017.coderising.jvm.constant; +import com.github.miniyk2012.coding2017.coderising.jvm.print.ConstantPoolPrinter; + public class NullConstantInfo extends ConstantInfo { public NullConstantInfo(){ @@ -9,5 +11,9 @@ public NullConstantInfo(){ public int getType() { return -1; } - + + @Override + public void accept(ConstantPoolPrinter.Visitor visitor) { + visitor.visitNullConstantInfo(this); + } } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/StringInfo.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/StringInfo.java index 428191ee6a..d2417bb1f2 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/StringInfo.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/StringInfo.java @@ -1,5 +1,7 @@ package com.github.miniyk2012.coding2017.coderising.jvm.constant; +import com.github.miniyk2012.coding2017.coderising.jvm.print.ConstantPoolPrinter; + public class StringInfo extends ConstantInfo{ private int type = ConstantInfo.STRING_INFO; private int index; @@ -22,5 +24,9 @@ public void setIndex(int index) { public String toString(){ return this.getConstantPool().getUTF8String(index); } - + + @Override + public void accept(ConstantPoolPrinter.Visitor visitor) { + visitor.visitStringInfo(this); + } } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/UTF8Info.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/UTF8Info.java index 3247ec1656..bd5f1246ed 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/UTF8Info.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/constant/UTF8Info.java @@ -1,5 +1,7 @@ package com.github.miniyk2012.coding2017.coderising.jvm.constant; +import com.github.miniyk2012.coding2017.coderising.jvm.print.ConstantPoolPrinter; + public class UTF8Info extends ConstantInfo{ private int type = ConstantInfo.UTF8_INFO; private int length ; @@ -27,4 +29,8 @@ public void setValue(String value) { this.value = value; } + @Override + public void accept(ConstantPoolPrinter.Visitor visitor) { + visitor.visitUTF8Info(this); + } } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java index b2887df85e..a7d4ed6b2d 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java @@ -24,8 +24,12 @@ public void print(){ ConstantPoolPrinter cnstPoolPrinter = new ConstantPoolPrinter(clzFile.getConstantPool()); cnstPoolPrinter.print(); - - } + System.out.println("{\n"); + + + System.out.println("}"); + + } public static void main(String[] args){ String path = ClassFilePrinter.class.getClassLoader().getResource("jvm").getPath(); diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java index f3c164be13..baa997202b 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java @@ -1,7 +1,9 @@ package com.github.miniyk2012.coding2017.coderising.jvm.print; -import com.github.miniyk2012.coding2017.coderising.jvm.constant.ConstantPool; +import com.github.miniyk2012.coding2017.coderising.jvm.clz.ClassFile; +import com.github.miniyk2012.coding2017.coderising.jvm.constant.*; +import com.github.miniyk2012.coding2017.coderising.jvm.loader.ClassFileLoader; public class ConstantPoolPrinter { ConstantPool pool; @@ -12,7 +14,73 @@ public class ConstantPoolPrinter { public void print(){ // todo: 实现javap System.out.println("Constant Pool:"); - - + Visitor visitor = new Visitor(); + for (int i=1; i<=pool.getSize(); i++) { + System.out.printf(" #"+(i)+" = "); + ConstantInfo constantInfo = pool.getConstantInfo(i); + try { + constantInfo.accept(visitor); + } catch (Exception e) { + } + System.out.printf("\n"); + } } + + public static class Visitor { + public void visitClassInfo(ClassInfo classInfo) { + System.out.printf("CLASS #" + classInfo.getUtf8Index()+" "); + System.out.printf("// "+classInfo.getClassName()); + } + public void visitFieldRefInfo(FieldRefInfo fieldRefInfo) { + System.out.printf("Fieldref #" + + fieldRefInfo.getClassInfoIndex() + ".#" + + fieldRefInfo.getNameAndTypeIndex() + + " "); + System.out.printf("// "+fieldRefInfo.getClassName()+ + "."+fieldRefInfo.getFieldName()+ + ":"+fieldRefInfo.getFieldType() + ); + } + public void visitMethodRefInfo(MethodRefInfo methodRefInfo) { + System.out.printf("Methodref #" + + methodRefInfo.getClassInfoIndex()+".#" + + methodRefInfo.getNameAndTypeIndex() + + " "); + System.out.printf("// "+methodRefInfo.getClassName()+"."+ + methodRefInfo.getMethodName()+":"+ + methodRefInfo.getParamAndReturnType() + ); + } + public void visitNameAndTypeInfo(NameAndTypeInfo nameAndTypeInfo) { + System.out.printf("NameAndType #" + + nameAndTypeInfo.getIndex1()+":#" + + nameAndTypeInfo.getIndex2() + + " "); + System.out.printf("// "+nameAndTypeInfo.getName()+":"+nameAndTypeInfo.getTypeInfo()); + + } + public void visitNullConstantInfo(NullConstantInfo nullConstantInfo) { + // 啥事都不干 + } + public void visitStringInfo(StringInfo stringInfo) { + System.out.printf("String #" + + stringInfo.getIndex() + + " "); + System.out.printf("// "+stringInfo.toString()); + } + public void visitUTF8Info(UTF8Info utf8Info) { + System.out.printf("Utf8 "+utf8Info.getValue()); + } + } + + public static void main(String[] args) { + String path = ClassFilePrinter.class.getClassLoader().getResource("jvm").getPath(); + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path); + String className = "com.github.miniyk2012.coding2017.jvm.test.EmployeeV1"; + + ClassFile clzFile = loader.loadClass(className); + ConstantPoolPrinter poolPrinter = new ConstantPoolPrinter(clzFile.getConstantPool()); + poolPrinter.print(); + } } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/Visitable.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/Visitable.java new file mode 100644 index 0000000000..3c8b8017db --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/Visitable.java @@ -0,0 +1,8 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.print; + +/** + * Created by thomas_young on 6/5/2017. + */ +public interface Visitable { + public void accept(ConstantPoolPrinter.Visitor visitor); +} From 5f652da9bff5627ef31d34f01f392c4bc3fcd406 Mon Sep 17 00:00:00 2001 From: thomas_young Date: Sun, 7 May 2017 21:37:29 +0800 Subject: [PATCH 02/12] =?UTF-8?q?javap=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coderising/jvm/field/Field.java | 25 ++++++++++- .../jvm/print/ClassFilePrinter.java | 11 ++++- .../jvm/print/ConstantPoolPrinter.java | 1 - .../coderising/jvm/print/FieldPrinter.java | 44 +++++++++++++++++++ .../coderising/jvm/print/MethodPrinter.java | 17 +++++++ 5 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/FieldPrinter.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/MethodPrinter.java diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/field/Field.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/field/Field.java index 7507e0a2af..f65d0f0f74 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/field/Field.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/field/Field.java @@ -5,11 +5,20 @@ import com.github.miniyk2012.coding2017.coderising.jvm.constant.UTF8Info; import com.github.miniyk2012.coding2017.coderising.jvm.loader.ByteCodeIterator; +import java.util.HashMap; +import java.util.Map; + public class Field { private int accessFlag; private int nameIndex; private int descriptorIndex; private ConstantPool pool; + + private static Map flagNameMap = new HashMap<>(); + { + flagNameMap.put(0x0001, "public-ACC_PUBLIC"); + flagNameMap.put(0x0002, "private-ACC_PRIVATE"); + } public Field(int accessFlag, int nameIndex, int descriptorIndex, ConstantPool pool) { @@ -27,7 +36,21 @@ public String toString() { String desc = pool.getUTF8String(descriptorIndex); return name +":"+ desc; } - + + public String getAccessFlagDescription() { + String accessFlag = flagNameMap.get(this.accessFlag); + // TODO: 6/5/2017 访问标志补全 + if (accessFlag == null) throw new RuntimeException("访问标志还未实现"); + return accessFlag; + } + + public String getType() { + return pool.getUTF8String(descriptorIndex); + } + + public String getName() { + return pool.getUTF8String(nameIndex); + } public static Field parse(ConstantPool pool, ByteCodeIterator iter){ diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java index a7d4ed6b2d..687e031280 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java @@ -23,9 +23,16 @@ public void print(){ System.out.println("major version:" + clzFile.getMinorVersion()); ConstantPoolPrinter cnstPoolPrinter = new ConstantPoolPrinter(clzFile.getConstantPool()); - cnstPoolPrinter.print(); + cnstPoolPrinter.print(); // 打印常量池 + System.out.println("{\n"); - + + FieldPrinter fieldPrinter = new FieldPrinter(clzFile); + fieldPrinter.print(); // 打印字段 + + + MethodPrinter methodPrinter = new MethodPrinter(clzFile); + methodPrinter.print(); // 打印方法 System.out.println("}"); diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java index baa997202b..7a27464830 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java @@ -12,7 +12,6 @@ public class ConstantPoolPrinter { } public void print(){ - // todo: 实现javap System.out.println("Constant Pool:"); Visitor visitor = new Visitor(); for (int i=1; i<=pool.getSize(); i++) { diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/FieldPrinter.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/FieldPrinter.java new file mode 100644 index 0000000000..c77aa48fef --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/FieldPrinter.java @@ -0,0 +1,44 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.print; + +import com.github.miniyk2012.coding2017.coderising.jvm.clz.ClassFile; +import com.github.miniyk2012.coding2017.coderising.jvm.field.Field; +import com.github.miniyk2012.coding2017.coderising.jvm.loader.ClassFileLoader; + +/** + * Created by thomas_young on 6/5/2017. + */ +public class FieldPrinter { + + private ClassFile classFile; + FieldPrinter(ClassFile classFile) { + this.classFile = classFile; + } + + public void print() { + for (Field field: classFile.getFields()) { + printSingleField(field); + System.out.println(); + } + } + + private void printSingleField(Field field) { + String accessFlag = field.getAccessFlagDescription(); + String type = field.getType(); + String name = field.getName(); + System.out.println(" " + accessFlag.split("-")[0] + " " + type.replace("/", ".") + " " + name + ";"); + System.out.println(" descriptor: " + type); + System.out.println(" flags: " + accessFlag.split("-")[1]); + } + + public static void main(String[] args) { + String path = ClassFilePrinter.class.getClassLoader().getResource("jvm").getPath(); + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path); + String className = "com.github.miniyk2012.coding2017.jvm.test.EmployeeV1"; + + ClassFile clzFile = loader.loadClass(className); + FieldPrinter fdPrinter = new FieldPrinter(clzFile); + fdPrinter.print(); + } +} + diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/MethodPrinter.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/MethodPrinter.java new file mode 100644 index 0000000000..9661bffe20 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/MethodPrinter.java @@ -0,0 +1,17 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.print; + +import com.github.miniyk2012.coding2017.coderising.jvm.clz.ClassFile; + +/** + * Created by thomas_young on 6/5/2017. + */ +public class MethodPrinter { + private ClassFile classFile; + MethodPrinter(ClassFile classFile) { + this.classFile = classFile; + } + + public void print() { + + } +} From 31d79fba46c32ee5416907b2b6126a256597f652 Mon Sep 17 00:00:00 2001 From: thomas_young Date: Sun, 7 May 2017 21:43:56 +0800 Subject: [PATCH 03/12] =?UTF-8?q?Jvm=E6=89=A7=E8=A1=8C=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jvm/engine/ExecutionResult.java | 57 +++++++++++ .../coderising/jvm/engine/ExecutorEngine.java | 35 +++++++ .../coderising/jvm/engine/Heap.java | 39 ++++++++ .../coderising/jvm/engine/JavaObject.java | 71 ++++++++++++++ .../coderising/jvm/engine/MethodArea.java | 68 +++++++++++++ .../coderising/jvm/engine/MiniJVM.java | 28 ++++++ .../coderising/jvm/engine/StackFrame.java | 95 +++++++++++++++++++ .../coderising/jvm/test/MiniJVMTest.java | 28 ++++++ 8 files changed, 421 insertions(+) create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/ExecutionResult.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/ExecutorEngine.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/Heap.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/JavaObject.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MethodArea.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MiniJVM.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/StackFrame.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/test/MiniJVMTest.java diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/ExecutionResult.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/ExecutionResult.java new file mode 100644 index 0000000000..9743a904d3 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/ExecutionResult.java @@ -0,0 +1,57 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.engine; + + +import com.github.miniyk2012.coding2017.coderising.jvm.method.Method; + +public class ExecutionResult { + public static final int RUN_NEXT_CMD = 1; + public static final int JUMP = 2; + public static final int EXIT_CURRENT_FRAME = 3; + public static final int PAUSE_AND_RUN_NEW_FRAME = 4; + + private int nextAction = RUN_NEXT_CMD; + + private int nextCmdOffset = 0; + + private Method nextMethod; + + public Method getNextMethod() { + return nextMethod; + } + public void setNextMethod(Method nextMethod) { + this.nextMethod = nextMethod; + } + + + + public void setNextAction(int action){ + this.nextAction = action; + } + public boolean isPauseAndRunNewFrame(){ + return this.nextAction == PAUSE_AND_RUN_NEW_FRAME; + } + public boolean isExitCurrentFrame(){ + return this.nextAction == EXIT_CURRENT_FRAME; + } + + public boolean isRunNextCmd(){ + return this.nextAction == RUN_NEXT_CMD; + } + + public boolean isJump(){ + return this.nextAction == JUMP; + } + + public int getNextCmdOffset() { + return nextCmdOffset; + } + + public void setNextCmdOffset(int nextCmdOffset) { + this.nextCmdOffset = nextCmdOffset; + } + + + + + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/ExecutorEngine.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/ExecutorEngine.java new file mode 100644 index 0000000000..ca4cdd78ab --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/ExecutorEngine.java @@ -0,0 +1,35 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.engine; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +import com.github.miniyk2012.coding2017.coderising.jvm.attr.CodeAttr; +import com.github.miniyk2012.coding2017.coderising.jvm.clz.ClassFile; +import com.github.miniyk2012.coding2017.coderising.jvm.cmd.ByteCodeCommand; +import com.github.miniyk2012.coding2017.coderising.jvm.constant.MethodRefInfo; +import com.github.miniyk2012.coding2017.coderising.jvm.method.Method; + +public class ExecutorEngine { + + private Stack stack = new Stack(); + + public ExecutorEngine() { + + } + + public void execute(Method mainMethod){ + + + + } + + + + private void setupFunctionCallParams(StackFrame currentFrame,StackFrame nextFrame) { + + + + } + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/Heap.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/Heap.java new file mode 100644 index 0000000000..3e346a1a6d --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/Heap.java @@ -0,0 +1,39 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.engine; + +public class Heap { + + /** + * 没有实现垃圾回收, 所以对于下面新创建的对象, 并没有记录到一个数据结构当中 + */ + + private static Heap instance = new Heap(); + private Heap() { + } + public static Heap getInstance(){ + return instance; + } + public JavaObject newObject(String clzName){ + + JavaObject jo = new JavaObject(JavaObject.OBJECT); + jo.setClassName(clzName); + return jo; + } + + public JavaObject newString(String value){ + JavaObject jo = new JavaObject(JavaObject.STRING); + jo.setStringValue(value); + return jo; + } + + public JavaObject newFloat(float value){ + JavaObject jo = new JavaObject(JavaObject.FLOAT); + jo.setFloatValue(value); + return jo; + } + public JavaObject newInt(int value){ + JavaObject jo = new JavaObject(JavaObject.INT); + jo.setIntValue(value); + return jo; + } + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/JavaObject.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/JavaObject.java new file mode 100644 index 0000000000..aaf606464b --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/JavaObject.java @@ -0,0 +1,71 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.engine; + +import java.util.HashMap; +import java.util.Map; + +public class JavaObject { + public static final int OBJECT = 1; + public static final int STRING = 2; + public static final int INT = 3; + public static final int FLOAT = 4; + + int type; + private String className; + + private Map fieldValues = new HashMap(); + + private String stringValue; + + private int intValue; + + private float floatValue; + + public void setFieldValue(String fieldName, JavaObject fieldValue){ + fieldValues.put(fieldName, fieldValue); + } + public JavaObject(int type){ + this.type = type; + } + public void setClassName(String className){ + this.className = className; + } + public void setStringValue(String value){ + stringValue = value; + } + public String getStringValue(){ + return this.stringValue; + } + public void setIntValue(int value) { + this.intValue = value; + } + public int getIntValue(){ + return this.intValue; + } + public int getType(){ + return type; + } + public JavaObject getFieldValue(String fieldName){ + return this.fieldValues.get(fieldName); + } + public String toString(){ + switch(this.getType()){ + case INT: + return String.valueOf(this.intValue); + case STRING: + return this.stringValue; + case OBJECT: + return this.className +":"+ this.fieldValues; + case FLOAT : + return String.valueOf(this.floatValue); + default: + return null; + } + } + public String getClassName(){ + return this.className; + } + public void setFloatValue(float value) { + this.floatValue = value; + } + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MethodArea.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MethodArea.java new file mode 100644 index 0000000000..dded057e1d --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MethodArea.java @@ -0,0 +1,68 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.engine; + +import java.util.HashMap; +import java.util.Map; + +import com.github.miniyk2012.coding2017.coderising.jvm.clz.ClassFile; +import com.github.miniyk2012.coding2017.coderising.jvm.constant.MethodRefInfo; +import com.github.miniyk2012.coding2017.coderising.jvm.loader.ClassFileLoader; +import com.github.miniyk2012.coding2017.coderising.jvm.method.Method; + +public class MethodArea { + + public static final MethodArea instance = new MethodArea(); + + /** + * 注意:我们做了极大的简化, ClassLoader 只有一个, 实际JVM中的ClassLoader,是一个双亲委托的模型 + */ + + private ClassFileLoader clzLoader = null; + + Map map = new HashMap(); + + private MethodArea(){ + } + + public static MethodArea getInstance(){ + return instance; + } + + public void setClassFileLoader(ClassFileLoader clzLoader){ + this.clzLoader = clzLoader; + } + + public Method getMainMethod(String className){ + + ClassFile clzFile = this.findClassFile(className); + + return clzFile.getMainMethod(); + } + + + public ClassFile findClassFile(String className){ + + if(map.get(className) != null){ + return map.get(className); + } + // 看来该class 文件还没有load过 + ClassFile clzFile = this.clzLoader.loadClass(className); + + map.put(className, clzFile); + + return clzFile; + + } + + + public Method getMethod(String className, String methodName, String paramAndReturnType){ + + return null; + } + + + public Method getMethod(MethodRefInfo methodRef){ + + return null; + + } +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MiniJVM.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MiniJVM.java new file mode 100644 index 0000000000..fa88ff2235 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MiniJVM.java @@ -0,0 +1,28 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.engine; +import java.io.FileNotFoundException; +import java.io.IOException; + +import com.github.miniyk2012.coding2017.coderising.jvm.loader.ClassFileLoader; + + +public class MiniJVM { + + public void run(String[]classPaths , String className) throws FileNotFoundException, IOException{ + + ClassFileLoader loader = new ClassFileLoader(); + for(int i=0;i localVariableTable = new ArrayList(); + private Stack oprandStack = new Stack(); + + int index = 0; + + private Method m = null; + + private StackFrame callerFrame = null; + + public StackFrame getCallerFrame() { + return callerFrame; + } + + public void setCallerFrame(StackFrame callerFrame) { + this.callerFrame = callerFrame; + } + + + + + public static StackFrame create(Method m){ + + StackFrame frame = new StackFrame( m ); + + return frame; + } + + + private StackFrame(Method m) { + this.m = m; + + } + + + + public JavaObject getLocalVariableValue(int index){ + return this.localVariableTable.get(index); + } + + public Stack getOprandStack(){ + return this.oprandStack; + } + + public int getNextCommandIndex(int offset){ + + ByteCodeCommand [] cmds = m.getCodeAttr().getCmds(); + for(int i=0;i values){ + this.localVariableTable = values; + } + + public void setLocalVariableValue(int index, JavaObject jo){ + //问题: 为什么要这么做?? + if(this.localVariableTable.size()-1 < index){ + for(int i=this.localVariableTable.size(); i<=index; i++){ + this.localVariableTable.add(null); + } + } + this.localVariableTable.set(index, jo); + + + } + + public Method getMethod(){ + return m; + } + + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/test/MiniJVMTest.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/test/MiniJVMTest.java new file mode 100644 index 0000000000..f05f973294 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/test/MiniJVMTest.java @@ -0,0 +1,28 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.test; + +import com.github.miniyk2012.coding2017.coderising.jvm.engine.MiniJVM; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +public class MiniJVMTest { + + static final String PATH = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\answer\\bin"; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testMain() throws Exception{ + String[] classPaths = {PATH}; + MiniJVM jvm = new MiniJVM(); + jvm.run(classPaths, "com.coderising.jvm.test.EmployeeV1"); + + } + +} From 316854bc7f374c30d42d4ae06c609840cd7d82c2 Mon Sep 17 00:00:00 2001 From: thomas_young Date: Thu, 11 May 2017 23:53:51 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E5=A2=9E=E5=8A=A02=E4=B8=AAclass?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coding2017/jvm/test/EmployeeV2.class | Bin 0 -> 1521 bytes .../coding2017/jvm/test/HourlyEmployee.class | Bin 0 -> 1060 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 group02/812350401/src/main/resources/jvm/com/github/miniyk2012/coding2017/jvm/test/EmployeeV2.class create mode 100644 group02/812350401/src/main/resources/jvm/com/github/miniyk2012/coding2017/jvm/test/HourlyEmployee.class diff --git a/group02/812350401/src/main/resources/jvm/com/github/miniyk2012/coding2017/jvm/test/EmployeeV2.class b/group02/812350401/src/main/resources/jvm/com/github/miniyk2012/coding2017/jvm/test/EmployeeV2.class new file mode 100644 index 0000000000000000000000000000000000000000..67ff119a683eb5a719e33e0189a1f4031cd248f7 GIT binary patch literal 1521 zcmah|ZExFD7(F*Jv6FgDmbPJS($!lBOVVy(UB}zHLg+eHDJ`H@kt&4XHnBPv$F5?h zQY1d|OAyjNgIFhl#1G&H@r{>ruRXfbA>{b_xxT*VoadaI-~RmhR{*QnGLaFu-U|n< zUf6esUgQObt)r7cD|Vx}wK+KU!?EjjS4x7ptQa;Lq$ zDNyd5t?$M|BHb6bv=IhTEQ7c!{gG=SFJL`%PnN#I_$5HGKY&f_^W#Nbx%_NO@ zVe3Yc*4FU65!TJH2 zUg4Rt%#7T4M;o1E)mB~`b#12UMf()_#6pYau)H~RohbHv-x-Ia;LySyfkOH|^!vyWdw*?^mAUTj7yrAUz7J)IYzNW}|C?ej4qdKQ1t}2P)4= zRefNiin6NOHf|-=hK;)_Z9@(Z8P?P*07-dFwY%YH*mECwD(~V8E4wSVm4moO&@7LB z7PEK_InGSZGO&2_^yr#rhfkAh)WfmJ**@3RzGCw^O3kHbm}=IZVde+D;dPE>7#uB* zd0qu>oWK>naguGMo8ycCnnvhK5oJigW>cEa^c<-Eh+6sjDQ>8zl{}k2VT#qiDJMx< zM2XiNE^A7gV1!611)6B2@au%na4n}hI72Gvx6^cFMk7>`ul^C8OGOJTVfg}9^_&q2 z))ivS{s)$7n^~!3Q!Gh7rFot`&XnrkVN&&do83Oegeu=k8_z;{T_HGdl|C=9We3xY zwT8u)nx9XlukbqqnQ0X!k55YX4e3;vwd|Vl;3*2#+E;7eW<;&j|NgJvNmo6^sxl{G zo72al&OHqtiY9Yyka3v?-_ndp!nKq!!x-My4H}H(9i6aJ!2|XOOd)bq{Vv{1m3*Pp zadq|=i2d^WrN!r1>nxpOo%e^lKRU}OY5EQUR|tHU5>`on?m+2HJ(^4<3#ab(u+EKhcV0k zed+Y1Z>#&nmBA6ky%(NI;auH$9~Hw23R zrHq5na&>HCi&5Sv6j+bjw>|S6dk?9ACEZpQ+XCAWTxGwa*jD(7SyiUeYPgL%8SDrc zQHfa$9lN+IkU3Sb&XASn$QSACN}KL-_2bn^)OuOe*nP(iq(+?^Y7|*Dl>0i$*q}@L z14?PkN#>-f%kDyvr+xIA6u2<3!nnWbnovb9iq_@s^sU#n8m2Kjmjl%{MWB{kU%@Yz zfM<&TNt0)ew@>t@_^a0&n-|dPTR*V!mG=Y+Jo8a*j(HlE`4nlZ$MIN2i8p4#z*>Z_ zW1W$S$fjx~X{8L4O3&y~EOOs)t#s=gmCG_(l$0l_LR3PJ11BYN*u%XE$Xhm{3K+j2 zK9s7(wPN)G^-kj)`s7KZ@i8LEa-4<(m`u+T<^diORG^7R6L2%SQ>XfOtbAcu XEJB)Quo2aK%xr1GOz^FsqMrN%Fxc9b literal 0 HcmV?d00001 From a1b8b3757af1bd29c32090cd193d2bedc2acc7b5 Mon Sep 17 00:00:00 2001 From: thomas_young Date: Sun, 21 May 2017 13:12:45 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E4=BD=9C=E4=B8=9A=205=E6=9C=8810=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coding2017/basic/tree/BinaryTreeNode.java | 35 +++++++++ .../coding2017/basic/tree/BinaryTreeUtil.java | 66 ++++++++++++++++ .../basic/tree/BinaryTreeUtilTest.java | 75 +++++++++++++++++++ .../coding2017/basic/tree/FileList.java | 10 +++ 4 files changed, 186 insertions(+) create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtilTest.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java new file mode 100644 index 0000000000..c5d01a5b49 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java @@ -0,0 +1,35 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +public class BinaryTreeNode { + + private T data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public BinaryTreeNode(T data){ + this.data=data; + } + 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(Object o){ + return null; + } + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java new file mode 100644 index 0000000000..22bc07366b --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java @@ -0,0 +1,66 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +public class BinaryTreeUtil { + /** + * 用递归的方式实现对二叉树的前序遍历, 需要通过BinaryTreeUtilTest测试 + * + * @param root + * @return + */ + public static List preOrderVisit(BinaryTreeNode root) { + List result = new ArrayList(); + + return result; + } + + /** + * 用递归的方式实现对二叉树的中遍历 + * + * @param root + * @return + */ + public static List inOrderVisit(BinaryTreeNode root) { + List result = new ArrayList(); + + return result; + } + + /** + * 用递归的方式实现对二叉树的后遍历 + * + * @param root + * @return + */ + public static List postOrderVisit(BinaryTreeNode root) { + List result = new ArrayList(); + + return result; + } + /** + * 用非递归的方式实现对二叉树的前序遍历 + * @param root + * @return + */ + public static List preOrderWithoutRecursion(BinaryTreeNode root) { + + List result = new ArrayList(); + + return result; + } + /** + * 用非递归的方式实现对二叉树的中序遍历 + * @param root + * @return + */ + public static List inOrderWithoutRecursion(BinaryTreeNode root) { + + List result = new ArrayList(); + + return result; + } + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtilTest.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtilTest.java new file mode 100644 index 0000000000..09137b0cfb --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtilTest.java @@ -0,0 +1,75 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class BinaryTreeUtilTest { + + BinaryTreeNode root = null; + @Before + public void setUp() throws Exception { + root = new BinaryTreeNode(1); + root.setLeft(new BinaryTreeNode(2)); + root.setRight(new BinaryTreeNode(5)); + root.getLeft().setLeft(new BinaryTreeNode(3)); + root.getLeft().setRight(new BinaryTreeNode(4)); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testPreOrderVisit() { + + List result = BinaryTreeUtil.preOrderVisit(root); + Assert.assertEquals("[1, 2, 3, 4, 5]", result.toString()); + + + } + @Test + public void testInOrderVisit() { + + + List result = BinaryTreeUtil.inOrderVisit(root); + Assert.assertEquals("[3, 2, 4, 1, 5]", result.toString()); + + } + + @Test + public void testPostOrderVisit() { + + + List result = BinaryTreeUtil.postOrderVisit(root); + Assert.assertEquals("[3, 4, 2, 5, 1]", result.toString()); + + } + + + @Test + public void testInOrderVisitWithoutRecursion() { + BinaryTreeNode node = root.getLeft().getRight(); + node.setLeft(new BinaryTreeNode(6)); + node.setRight(new BinaryTreeNode(7)); + + List result = BinaryTreeUtil.inOrderWithoutRecursion(root); + Assert.assertEquals("[3, 2, 6, 4, 7, 1, 5]", result.toString()); + + } + @Test + public void testPreOrderVisitWithoutRecursion() { + BinaryTreeNode node = root.getLeft().getRight(); + node.setLeft(new BinaryTreeNode(6)); + node.setRight(new BinaryTreeNode(7)); + + List result = BinaryTreeUtil.preOrderWithoutRecursion(root); + Assert.assertEquals("[1, 2, 3, 4, 6, 7, 5]", result.toString()); + + } +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java new file mode 100644 index 0000000000..df0747e948 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java @@ -0,0 +1,10 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +import java.io.File; + +public class FileList { + public void list(File f) { + } + + +} From c3737dab87e2dc00b0046247f517aa52eca455ea Mon Sep 17 00:00:00 2001 From: thomas_young Date: Sun, 21 May 2017 17:08:28 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E5=89=8D=E5=BA=8F=E9=81=8D=E5=8E=86?= =?UTF-8?q?=EF=BC=8C=E4=B8=AD=E5=BA=8F=E9=81=8D=E5=8E=86=EF=BC=8C=E5=90=8E?= =?UTF-8?q?=E5=BA=8F=E9=81=8D=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coding2017/basic/tree/BinaryTreeUtil.java | 87 +++++++++++++++---- .../coding2017/basic/tree/FileList.java | 2 +- 2 files changed, 71 insertions(+), 18 deletions(-) diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java index 22bc07366b..184936cde8 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java @@ -1,44 +1,64 @@ package com.github.miniyk2012.coding2017.basic.tree; -import java.util.ArrayList; -import java.util.List; -import java.util.Stack; + +import java.util.*; public class BinaryTreeUtil { /** * 用递归的方式实现对二叉树的前序遍历, 需要通过BinaryTreeUtilTest测试 - * + * 先访问root,再访问左子树,再访问右子树 * @param root * @return */ public static List preOrderVisit(BinaryTreeNode root) { - List result = new ArrayList(); - + List result = new ArrayList<>(); + if (root == null) { + return result; + } + result.add(root.getData()); + BinaryTreeNode leftTreeNode = root.getLeft(); + result.addAll(preOrderVisit(leftTreeNode)); + BinaryTreeNode rightTreeNode = root.getRight(); + result.addAll(preOrderVisit(rightTreeNode)); return result; } /** * 用递归的方式实现对二叉树的中遍历 - * + * 先左后根再右 * @param root * @return */ public static List inOrderVisit(BinaryTreeNode root) { - List result = new ArrayList(); - + List result = new ArrayList<>(); + if (root == null) { + return result; + } + BinaryTreeNode leftTreeNode = root.getLeft(); + result.addAll(inOrderVisit(leftTreeNode)); + result.add(root.getData()); + BinaryTreeNode rightTreeNode = root.getRight(); + result.addAll(inOrderVisit(rightTreeNode)); return result; } /** * 用递归的方式实现对二叉树的后遍历 - * + * 左右根 * @param root * @return */ public static List postOrderVisit(BinaryTreeNode root) { - List result = new ArrayList(); - - return result; + List result = new ArrayList<>(); + if (root == null) { + return result; + } + BinaryTreeNode leftTreeNode = root.getLeft(); + result.addAll(postOrderVisit(leftTreeNode)); + BinaryTreeNode rightTreeNode = root.getRight(); + result.addAll(postOrderVisit(rightTreeNode)); + result.add(root.getData()); + return result; } /** * 用非递归的方式实现对二叉树的前序遍历 @@ -47,19 +67,52 @@ public static List postOrderVisit(BinaryTreeNode root) { */ public static List preOrderWithoutRecursion(BinaryTreeNode root) { - List result = new ArrayList(); - - return result; + List result = new ArrayList(); + Stack> stack = new Stack<>(); // 存放接下来要访问的节点 + if (root == null) { + return result; + } + stack.push(root); + while(!stack.isEmpty()) { + BinaryTreeNode top = stack.pop(); + result.add(top.getData()); + if (top.getRight() != null) { + stack.add(top.getRight()); + } + if (top.getLeft() != null) { + stack.add(top.getLeft()); + } + } + return result; } /** * 用非递归的方式实现对二叉树的中序遍历 + * 先左后根再右 * @param root * @return */ public static List inOrderWithoutRecursion(BinaryTreeNode root) { List result = new ArrayList(); - + if (root == null) { + return result; + } + Stack> stack = new Stack<>(); + stack.push(root); + BinaryTreeNode top = stack.peek(); + while (!stack.isEmpty()) { + if (top.getLeft() != null) { + stack.push(top.getLeft()); + top = top.getLeft(); + } else { + top = stack.pop(); + result.add(top.getData()); + if (top.getRight() != null) { + stack.push(top.getRight()); + top = top.getRight(); + } + } + } return result; } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java index df0747e948..acd5bf08b0 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java @@ -3,7 +3,7 @@ import java.io.File; public class FileList { - public void list(File f) { + public void list(File f) { } From 835ea31d40f94543cc0ebc5b0a8efe37cafdd2f6 Mon Sep 17 00:00:00 2001 From: thomas_young Date: Sun, 21 May 2017 17:13:27 +0800 Subject: [PATCH 07/12] binary search tree init --- .../basic/tree/BinarySearchTree.java | 29 ++++++++ .../basic/tree/BinarySearchTreeTest.java | 67 +++++++++++++++++++ .../coding2017/basic/tree/BinaryTreeNode.java | 6 +- 3 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java create mode 100644 group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java new file mode 100644 index 0000000000..07db3ac320 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java @@ -0,0 +1,29 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +public class BinarySearchTree { + + BinaryTreeNode root; + public BinarySearchTree(BinaryTreeNode root){ + this.root = root; + } + public BinaryTreeNode getRoot(){ + return root; + } + public T findMin(){ + return null; + } + public T findMax(){ + return null; + } + public int height() { + return -1; + } + public int size() { + return -1; + } + public void remove(T e){ + + } + +} + diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java new file mode 100644 index 0000000000..3ad390e879 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java @@ -0,0 +1,67 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class BinarySearchTreeTest { + + BinarySearchTree tree = null; + + @Before + public void setUp() throws Exception { + BinaryTreeNode root = new BinaryTreeNode(6); + root.left = new BinaryTreeNode(2); + root.right = new BinaryTreeNode(8); + root.left.left = new BinaryTreeNode(1); + root.left.right = new BinaryTreeNode(4); + root.left.right.left = new BinaryTreeNode(3); + tree = new BinarySearchTree(root); + } + + @After + public void tearDown() throws Exception { + tree = null; + } + + @Test + public void testFindMin() { + Assert.assertEquals(1, tree.findMin().intValue()); + + } + + @Test + public void testFindMax() { + Assert.assertEquals(8, tree.findMax().intValue()); + } + + @Test + public void testHeight() { + Assert.assertEquals(4, tree.height()); + } + + @Test + public void testSize() { + Assert.assertEquals(6, tree.size()); + } + + @Test + public void testRemoveLeaf() { + tree.remove(4); + BinaryTreeNode root= tree.getRoot(); + Assert.assertEquals(3, root.left.right.data.intValue()); + + } + @Test + public void testRemoveMiddleNode() { + tree.remove(2); + BinaryTreeNode root= tree.getRoot(); + Assert.assertEquals(3, root.left.data.intValue()); + Assert.assertEquals(4, root.left.right.data.intValue()); + } +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java index c5d01a5b49..82e3957e7f 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java @@ -2,9 +2,9 @@ public class BinaryTreeNode { - private T data; - private BinaryTreeNode left; - private BinaryTreeNode right; + protected T data; + protected BinaryTreeNode left; + protected BinaryTreeNode right; public BinaryTreeNode(T data){ this.data=data; From 91de119ca16cff2970bbcf34c4b91747800e7224 Mon Sep 17 00:00:00 2001 From: thomas_young Date: Sun, 21 May 2017 22:51:52 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=8A=82=E7=82=B9?= =?UTF-8?q?=EF=BC=8C=E6=A0=91=E7=9A=84=E5=B1=82=E6=95=B0=EF=BC=8C=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E6=95=B0=EF=BC=8C=E6=9C=80=E5=A4=A7=E5=80=BC=EF=BC=8C?= =?UTF-8?q?=E6=9C=80=E5=B0=8F=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/tree/BinarySearchTree.java | 104 +++++++++++++++++- 1 file changed, 98 insertions(+), 6 deletions(-) diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java index 07db3ac320..9780ccd8b0 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java @@ -1,5 +1,7 @@ package com.github.miniyk2012.coding2017.basic.tree; +import java.util.NoSuchElementException; + public class BinarySearchTree { BinaryTreeNode root; @@ -9,21 +11,111 @@ public BinarySearchTree(BinaryTreeNode root){ public BinaryTreeNode getRoot(){ return root; } - public T findMin(){ - return null; + + public T findMin() { + if (root == null) { + throw new NoSuchElementException("根节点为空"); + } + + return findMin(root); } + + private T findMin(BinaryTreeNode root) { + BinaryTreeNode p = root; + while (p.left!=null) { + p = p.left; + } + return p.getData(); + } + public T findMax(){ - return null; + if (root == null) { + throw new NoSuchElementException("根节点为空"); + } + return findMax(root); } + + private T findMax(BinaryTreeNode root) { + BinaryTreeNode p = root; + while (p.right!=null) { + p = p.right; + } + return p.getData(); + } + public int height() { - return -1; + if (root == null) { + return 0; + } + return getHeight(root); } + + private int getHeight(BinaryTreeNode root) { + if (root == null) { + return 0; + } + int leftHeight = getHeight(root.left); + int rightHeight = getHeight(root.right); + return 1 + (leftHeight>rightHeight?leftHeight:rightHeight); + } + public int size() { - return -1; + if (root == null) { + return 0; + } + return getSize(root); } + + private int getSize(BinaryTreeNode root) { + if (root == null) { + return 0; + } + int leftSize = getSize(root.left); + int rightSize = getSize(root.right); + return 1 + leftSize + rightSize; + } public void remove(T e){ - + if (root == null) { + throw new NoSuchElementException("根节点为空"); + } + remove(e, root); } + + private BinaryTreeNode remove(T e, BinaryTreeNode root) { + if (root == null) { + throw new NoSuchElementException("不存在该元素,删除失败"); + } + if (root.data.compareTo(e) == 0) { + if (root.left == null && root.right == null) { + return null; + } else if (root.right == null && root.left != null) { + return root.left; + } else if (root.right != null && root.left == null) { + return root.right; + } else { + BinaryTreeNode minParent = findMinParent(root.right); + root.data = minParent.left.data; + minParent.left = null; + return root; + } + } else if (root.data.compareTo(e) < 0) { + root.right = remove(e, root.right); + return root; + } else { + root.left = remove(e, root.left); + return root; + } + } + + private BinaryTreeNode findMinParent(BinaryTreeNode root) { + BinaryTreeNode p = root; + BinaryTreeNode parent = null; + while (p.left!=null) { + parent = p; + p = p.left; + } + return parent; + } } From fcdb090e8f521b7bc3c5f1fc9257deba2897ab87 Mon Sep 17 00:00:00 2001 From: thomas_young Date: Sun, 21 May 2017 23:28:42 +0800 Subject: [PATCH 09/12] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/tree/BinarySearchTree.java | 40 ++++++++----------- .../basic/tree/BinarySearchTreeTest.java | 12 ++++++ 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java index 9780ccd8b0..5fe9ea7e11 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java @@ -78,44 +78,38 @@ public void remove(T e){ if (root == null) { throw new NoSuchElementException("根节点为空"); } - remove(e, root); + root = remove(e, root); } private BinaryTreeNode remove(T e, BinaryTreeNode root) { if (root == null) { throw new NoSuchElementException("不存在该元素,删除失败"); } - if (root.data.compareTo(e) == 0) { - if (root.left == null && root.right == null) { - return null; - } else if (root.right == null && root.left != null) { - return root.left; - } else if (root.right != null && root.left == null) { + int cmp = root.data.compareTo(e); + if (cmp == 0) { + if (root.left == null) { return root.right; - } else { - BinaryTreeNode minParent = findMinParent(root.right); - root.data = minParent.left.data; - minParent.left = null; - return root; } - } else if (root.data.compareTo(e) < 0) { + if (root.right == null) { + return root.left; + } + T min = findMin(root.right); + root.data = min; + root.right = deleteMin(root.right); + } else if (cmp < 0) { root.right = remove(e, root.right); - return root; } else { root.left = remove(e, root.left); - return root; } + return root; } - private BinaryTreeNode findMinParent(BinaryTreeNode root) { - BinaryTreeNode p = root; - BinaryTreeNode parent = null; - while (p.left!=null) { - parent = p; - p = p.left; + private BinaryTreeNode deleteMin(BinaryTreeNode root) { + if (root.left == null) { + return root.right; } - return parent; + root.left = deleteMin(root.left); + return root; } - } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java index 3ad390e879..127064a721 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java @@ -64,4 +64,16 @@ public void testRemoveMiddleNode() { Assert.assertEquals(3, root.left.data.intValue()); Assert.assertEquals(4, root.left.right.data.intValue()); } + + @Test + public void testRemoveRoot() { + tree.remove(6); + BinaryTreeNode root= tree.getRoot(); + Assert.assertEquals(8, root.data.intValue()); + Assert.assertEquals(2, root.left.data.intValue()); + Assert.assertNull(root.right); + Assert.assertEquals(3, root.left.right.left.data.intValue()); + + } + } From 409ca564c9594f394a324dc51bb5d25f6f774356 Mon Sep 17 00:00:00 2001 From: thomas_young Date: Mon, 22 May 2017 23:57:24 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E7=AC=AC=E4=B9=9D=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9Ainit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coding2017/basic/tree/BinarySearchTree.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java index 5fe9ea7e11..2a3f0e26d5 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java @@ -1,5 +1,6 @@ package com.github.miniyk2012.coding2017.basic.tree; +import java.util.List; import java.util.NoSuchElementException; public class BinarySearchTree { @@ -111,5 +112,20 @@ private BinaryTreeNode deleteMin(BinaryTreeNode root) { root.left = deleteMin(root.left); return root; } + + public List levelVisit(){ + + return null; + } + public boolean isValid(){ + return false; + } + public T getLowestCommonAncestor(T n1, T n2){ + return null; + + } + public List getNodesBetween(T n1, T n2){ + return null; + } } From f9254448c34dc6317c9e76d3e7bd49dd3686001e Mon Sep 17 00:00:00 2001 From: thomas_young Date: Tue, 23 May 2017 00:34:02 +0800 Subject: [PATCH 11/12] =?UTF-8?q?FileList=E9=9D=9E=E5=B8=B8=E9=9A=BE?= =?UTF-8?q?=E7=9C=8B=E7=9A=84=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coding2017/basic/tree/FileList.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java index acd5bf08b0..62c280985e 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java @@ -1,10 +1,33 @@ package com.github.miniyk2012.coding2017.basic.tree; import java.io.File; +import java.io.FileNotFoundException; public class FileList { - public void list(File f) { + public void list(File f) throws FileNotFoundException { + if (!f.exists()) { + throw new FileNotFoundException("该文件不存在"); + } + showFiles(f, 0); } + private void showFiles(File f, int i) { + if (f.isFile()) { + System.out.printf(f.getName() + " "); + } else { + System.out.println(); + System.out.println(i+" depth "+f.getAbsolutePath()); + for (File subFile: f.listFiles()) { + showFiles(subFile, i+1); + } + } + } + + + public static void main(String[] args) throws FileNotFoundException { + File f = new File("/Users/thomas_young/Documents/code/coding2017/group02/812350401/src/main/java/com/github/miniyk2012/coding2017"); + FileList fileList = new FileList(); + fileList.list(f); + } } From e2e7c6413af633ae9fe94e0d49023416ed4977af Mon Sep 17 00:00:00 2001 From: thomas_young Date: Tue, 23 May 2017 00:45:30 +0800 Subject: [PATCH 12/12] =?UTF-8?q?Filelist=E7=AC=AC=E4=BA=8C=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coding2017/basic/tree/FileList.java | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java index 62c280985e..c2422df4cd 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java @@ -8,21 +8,30 @@ public void list(File f) throws FileNotFoundException { if (!f.exists()) { throw new FileNotFoundException("该文件不存在"); } - showFiles(f, 0); + list(f, 0); } - private void showFiles(File f, int i) { - if (f.isFile()) { - System.out.printf(f.getName() + " "); - } else { - System.out.println(); - System.out.println(i+" depth "+f.getAbsolutePath()); - for (File subFile: f.listFiles()) { - showFiles(subFile, i+1); + private void list(File f, int depth) { + printName(f, depth); + if (f.isDirectory()) { + for (File subFile: f.listFiles()) { + list(subFile, depth+1); } } } + private void printName(File f, int depth) { + String name = f.getName(); + for (int i=0; i