From 4b7978c148dc753e526e487db6c31fe1942c6edc Mon Sep 17 00:00:00 2001 From: 10094714 Date: Fri, 14 Apr 2017 16:30:58 +0800 Subject: [PATCH 1/4] =?UTF-8?q?jvm=E7=AC=AC=E4=B8=89=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../learning/java/jvm/attr/CodeAttr.java | 69 ++++++- .../java/jvm/attr/LineNumberTable.java | 47 +++-- .../java/jvm/attr/LocalVariableTable.java | 39 +++- .../learning/java/jvm/field/Field.java | 31 ++- .../java/jvm/loader/ClassFileParser.java | 178 +++++++++++++++--- .../learning/java/jvm/method/Method.java | 45 ++++- .../learning/java/stack/expr/InfixExpr.java | 14 ++ .../java/jvm/ClassFileloaderTest.java | 8 +- .../chaoswang/learning/java/jvm/ClassInfo.txt | 162 ++++++++++++++++ .../java/stack/expr/InfixExprTest.java | 48 +++++ 10 files changed, 592 insertions(+), 49 deletions(-) create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixExpr.java create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassInfo.txt create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/InfixExprTest.java diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/attr/CodeAttr.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/attr/CodeAttr.java index f7157b9d3c..6ca2fd2692 100644 --- a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/attr/CodeAttr.java +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/attr/CodeAttr.java @@ -1,6 +1,7 @@ package com.github.chaoswang.learning.java.jvm.attr; import com.github.chaoswang.learning.java.jvm.clz.ClassFile; +import com.github.chaoswang.learning.java.jvm.constant.ConstantPool; import com.github.chaoswang.learning.java.jvm.loader.ByteCodeIterator; public class CodeAttr extends AttributeInfo { @@ -37,10 +38,74 @@ public void setLocalVariableTable(LocalVariableTable t) { this.localVarTable = t; } - public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ +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(); - return null; + String code = iter.nextUxToHexString(codeLen); + + System.out.println(code); + + //ByteCodeCommand[] cmds = ByteCodeCommand.parse(clzFile,code); + + CodeAttr codeAttr = new CodeAttr(attrNameIndex,attrLen, maxStack,maxLocals,codeLen,code); + + int exceptionTableLen = iter.nextU2ToInt(); + //TODO 处理exception + if(exceptionTableLen>0){ + String exTable = iter.nextUxToHexString(exceptionTableLen); + System.out.println("Encountered exception table , just ignore it :" + exTable); + + } + + + int subAttrCount = iter.nextU2ToInt(); + + for(int x=1; x<=subAttrCount; x++){ + int subAttrIndex = iter.nextU2ToInt(); + String subAttrName = clzFile.getConstantPool().getUTF8String(subAttrIndex); + + //已经向前移动了U2, 现在退回去。 + iter.back(2); + //line item table + if(AttributeInfo.LINE_NUM_TABLE.equalsIgnoreCase(subAttrName)){ + + LineNumberTable t = LineNumberTable.parse(iter); + codeAttr.setLineNumberTable(t); + } + else if(AttributeInfo.LOCAL_VAR_TABLE.equalsIgnoreCase(subAttrName)){ + LocalVariableTable t = LocalVariableTable.parse(iter); + codeAttr.setLocalVariableTable(t); + } + else if (AttributeInfo.STACK_MAP_TABLE.equalsIgnoreCase(subAttrName)){ + StackMapTable t = StackMapTable.parse(iter); + codeAttr.setStackMapTable(t); + } + else{ + throw new RuntimeException("Need code to process " + subAttrName); + } + + + } + + return codeAttr; + } + + + public String toString(ConstantPool pool){ + StringBuilder buffer = new StringBuilder(); + buffer.append("Code:").append(code).append("\n"); + /*for(int i=0;i items = new ArrayList(); - - private static class LineNumberItem { + + 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) { + 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; + + public static LineNumberTable parse(ByteCodeIterator iter){ + + int index = iter.nextU2ToInt(); + int len = iter.nextU4ToInt(); + + LineNumberTable table = new LineNumberTable(index,len); + + int itemLen = iter.nextU2ToInt(); + + for(int i=1; i<=itemLen; i++){ + LineNumberItem item = new LineNumberItem(); + item.setStartPC(iter.nextU2ToInt()); + item.setLineNum(iter.nextU2ToInt()); + table.addLineNumberItem(item); + } + return table; + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + buffer.append("Line Number Table:\n"); + for(LineNumberItem item : items){ + buffer.append("startPC:"+item.getStartPC()).append(","); + buffer.append("lineNum:"+item.getLineNum()).append("\n"); + } + buffer.append("\n"); + return buffer.toString(); + } } diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/attr/LocalVariableTable.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/attr/LocalVariableTable.java index c56aee7f26..8ce765441d 100644 --- a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/attr/LocalVariableTable.java +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/attr/LocalVariableTable.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +import com.github.chaoswang.learning.java.jvm.constant.ConstantPool; import com.github.chaoswang.learning.java.jvm.loader.ByteCodeIterator; public class LocalVariableTable extends AttributeInfo{ @@ -13,11 +14,43 @@ public LocalVariableTable(int attrNameIndex, int attrLen) { super(attrNameIndex, attrLen); } + + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + public static LocalVariableTable parse(ByteCodeIterator iter){ - return null; + int index = iter.nextU2ToInt(); + int len = iter.nextU4ToInt(); + + LocalVariableTable table = new LocalVariableTable(index,len); + + int itemLen = iter.nextU2ToInt(); + + for(int i=1; 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); + + + public String toString(ConstantPool pool){ + StringBuilder buffer = new StringBuilder(); + buffer.append("Local Variable Table:\n"); + for(LocalVariableItem item : items){ + buffer.append("startPC:"+item.getStartPC()).append(","); + buffer.append("name:"+pool.getUTF8String(item.getNameIndex())).append(","); + buffer.append("desc:"+pool.getUTF8String(item.getDescIndex())).append(","); + buffer.append("slotIndex:"+ item.getIndex()).append("\n"); + } + buffer.append("\n"); + return buffer.toString(); } } diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/field/Field.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/field/Field.java index c0ef09f88a..ffa930a266 100644 --- a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/field/Field.java +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/field/Field.java @@ -1,8 +1,18 @@ package com.github.chaoswang.learning.java.jvm.field; import com.github.chaoswang.learning.java.jvm.constant.ConstantPool; +import com.github.chaoswang.learning.java.jvm.constant.UTF8Info; import com.github.chaoswang.learning.java.jvm.loader.ByteCodeIterator; +/** + * field_info { + * u2 access_flags; + * u2 name_index; + * u2 descriptor_index; + * u2 attributes_count; + * attribute_info attributes[attributes_count]; + * + */ public class Field { private int accessFlag; private int nameIndex; @@ -20,12 +30,29 @@ public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool po this.pool = pool; } - + 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){ - return null; + int accessFlag = iter.nextU2ToInt(); + int nameIndex = iter.nextU2ToInt(); + int descIndex = iter.nextU2ToInt(); + int attribCount = iter.nextU2ToInt(); + //System.out.println("field attribute count:"+ attribCount); + + Field f = new Field(accessFlag, nameIndex, descIndex,pool); + + if(attribCount > 0){ + throw new RuntimeException("Field Attribute has not been implemented"); + } + + return f; } } \ No newline at end of file diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/loader/ClassFileParser.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/loader/ClassFileParser.java index 3b133dba93..abfced862b 100644 --- a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/loader/ClassFileParser.java +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/loader/ClassFileParser.java @@ -1,11 +1,20 @@ package com.github.chaoswang.learning.java.jvm.loader; +import java.io.UnsupportedEncodingException; + import com.github.chaoswang.learning.java.jvm.clz.AccessFlag; import com.github.chaoswang.learning.java.jvm.clz.ClassFile; import com.github.chaoswang.learning.java.jvm.clz.ClassIndex; import com.github.chaoswang.learning.java.jvm.constant.ClassInfo; import com.github.chaoswang.learning.java.jvm.constant.ConstantPool; +import com.github.chaoswang.learning.java.jvm.constant.FieldRefInfo; +import com.github.chaoswang.learning.java.jvm.constant.MethodRefInfo; +import com.github.chaoswang.learning.java.jvm.constant.NameAndTypeInfo; +import com.github.chaoswang.learning.java.jvm.constant.NullConstantInfo; +import com.github.chaoswang.learning.java.jvm.constant.StringInfo; import com.github.chaoswang.learning.java.jvm.constant.UTF8Info; +import com.github.chaoswang.learning.java.jvm.field.Field; +import com.github.chaoswang.learning.java.jvm.method.Method; public class ClassFileParser { @@ -17,58 +26,181 @@ public ClassFile parse(byte[] codes) { codeIterator.getBytes(4); classFile.setMinorVersion(codeIterator.nextU2ToInt()); classFile.setMajorVersion(codeIterator.nextU2ToInt()); + //跳过常量池计数器 + codeIterator.getBytes(2); + //解析常量池 + classFile.setConstPool(parseConstantPool(codeIterator)); + classFile.setAccessFlag(parseAccessFlag(codeIterator)); + classFile.setClassIndex(parseClassIndex(codeIterator)); + + parseInterfaces(codeIterator); + parseFileds(classFile, codeIterator); + parseMethods(classFile, codeIterator); return classFile; } private AccessFlag parseAccessFlag(ByteCodeIterator iter) { - //得跳过常量池,常量池的长度是多少? AccessFlag accessFlag = new AccessFlag(iter.nextU2ToInt()); return accessFlag; } private ClassIndex parseClassIndex(ByteCodeIterator iter) { - - return null; - + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(iter.nextU2ToInt()); + classIndex.setSuperClassIndex(iter.nextU2ToInt()); + return classIndex; } private ConstantPool parseConstantPool(ByteCodeIterator iter) { ConstantPool pool = new ConstantPool(); - ClassInfo classInfo = new ClassInfo(pool); - //classInfo tag值 - iter.nextU1toInt(); - classInfo.setUtf8Index(iter.nextU2ToInt()); - pool.addConstantInfo(classInfo); + pool.addConstantInfo(new NullConstantInfo());//占个位置,因为常量池编号从1开始 + + parseClassInfo(iter, pool);//#1 + parseUTF8Info(iter, pool); + parseClassInfo(iter, pool); + for(int i=0;i<8;i++){ + parseUTF8Info(iter, pool); + } + parseMethodRefInfo(iter, pool);//#12 + parseNameAndTypeInfo(iter, pool); + parseUTF8Info(iter, pool); + parseFieldRefInfo(iter, pool); + parseNameAndTypeInfo(iter, pool); + parseFieldRefInfo(iter, pool); + parseNameAndTypeInfo(iter, pool); + for(int i=0;i<9;i++){ + parseUTF8Info(iter, pool); + } + parseFieldRefInfo(iter, pool);//#28 + parseClassInfo(iter, pool); + parseUTF8Info(iter, pool); + parseNameAndTypeInfo(iter, pool);//#31 + for(int i=0;i<2;i++){ + parseUTF8Info(iter, pool); + } + parseStringInfo(iter, pool);//#34 + parseUTF8Info(iter, pool); + parseMethodRefInfo(iter, pool); + parseClassInfo(iter, pool); + parseUTF8Info(iter, pool); + parseNameAndTypeInfo(iter, pool);//#39 + for(int i=0;i<3;i++){ + parseUTF8Info(iter, pool); + } + parseStringInfo(iter, pool);//#43 + parseUTF8Info(iter, pool); + parseMethodRefInfo(iter, pool); + parseNameAndTypeInfo(iter, pool); + parseMethodRefInfo(iter, pool); + parseNameAndTypeInfo(iter, pool);//#48 + for(int i=0;i<5;i++){ + parseUTF8Info(iter, pool); + } + return pool; + } + + private void parseStringInfo(ByteCodeIterator iter, ConstantPool pool) { + StringInfo stringInfo = new StringInfo(pool); + //tag值 + iter.nextU1toInt(); + //string_index + stringInfo.setIndex(iter.nextU2ToInt()); + pool.addConstantInfo(stringInfo); + } + + + private void parseFieldRefInfo(ByteCodeIterator iter, ConstantPool pool) { + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + //tag值 + iter.nextU1toInt(); + //class_index + fieldRefInfo.setClassInfoIndex(iter.nextU2ToInt()); + //name_and_type_index + fieldRefInfo.setNameAndTypeIndex(iter.nextU2ToInt()); + pool.addConstantInfo(fieldRefInfo); + } + + + private void parseNameAndTypeInfo(ByteCodeIterator iter, ConstantPool pool) { + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + //tag值 + iter.nextU1toInt(); + //name_index + nameAndTypeInfo.setIndex1(iter.nextU2ToInt()); + //descriptor_index + nameAndTypeInfo.setIndex2(iter.nextU2ToInt()); + pool.addConstantInfo(nameAndTypeInfo); + } + + + private void parseMethodRefInfo(ByteCodeIterator iter, ConstantPool pool) { + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + //tag值 + iter.nextU1toInt(); + //class_index + methodRefInfo.setClassInfoIndex(iter.nextU2ToInt()); + //name_and_type_index + methodRefInfo.setNameAndTypeIndex(iter.nextU2ToInt()); + pool.addConstantInfo(methodRefInfo); + } + + + private void parseUTF8Info(ByteCodeIterator iter, ConstantPool pool) { UTF8Info utf8Info = new UTF8Info(pool); //UTF8Info tag值 iter.nextU1toInt(); //UTF8Info length值 int length = iter.nextU2ToInt(); utf8Info.setLength(length); - utf8Info.setValue(iter.nextUxToHexString(length)); + byte[] byteArray = iter.getBytes(length); + String value = null; + try { + value = new String(byteArray, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + utf8Info.setValue(value); pool.addConstantInfo(utf8Info); - - classInfo = new ClassInfo(pool); + } + + private void parseClassInfo(ByteCodeIterator iter, ConstantPool pool) { + ClassInfo classInfo = new ClassInfo(pool); //classInfo tag值 iter.nextU1toInt(); classInfo.setUtf8Index(iter.nextU2ToInt()); pool.addConstantInfo(classInfo); + } + + private void parseInterfaces(ByteCodeIterator iter) { + int interfaceCount = iter.nextU2ToInt(); + + System.out.println("interfaceCount:" + interfaceCount); + + // TODO : 如果实现了interface, 这里需要解析 + } + + private void parseFileds(ClassFile clzFile, ByteCodeIterator iter) { + int fieldCount = iter.nextU2ToInt(); - for(int i=0;i<8;i++){ - utf8Info = new UTF8Info(pool); - //UTF8Info tag值 - iter.nextU1toInt(); - //UTF8Info length值 - length = iter.nextU2ToInt(); - utf8Info.setLength(length); - utf8Info.setValue(iter.nextUxToHexString(length)); - pool.addConstantInfo(utf8Info); + for (int i = 1; i <= fieldCount; i++) { + Field f = Field.parse(clzFile.getConstantPool(), iter); + clzFile.addField(f); } - - return pool; + + } + + private void parseMethods(ClassFile clzFile, ByteCodeIterator iter) { + + int methodCount = iter.nextU2ToInt(); + + for (int i = 1; i <= methodCount; i++) { + Method m = Method.parse(clzFile, iter); + clzFile.addMethod(m); + } + } } \ No newline at end of file diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/method/Method.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/method/Method.java index c55cb5ac25..1c1546a02d 100644 --- a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/method/Method.java +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/method/Method.java @@ -1,10 +1,14 @@ package com.github.chaoswang.learning.java.jvm.method; +import com.github.chaoswang.learning.java.jvm.attr.AttributeInfo; import com.github.chaoswang.learning.java.jvm.attr.CodeAttr; import com.github.chaoswang.learning.java.jvm.clz.ClassFile; +import com.github.chaoswang.learning.java.jvm.constant.ConstantPool; +import com.github.chaoswang.learning.java.jvm.constant.UTF8Info; import com.github.chaoswang.learning.java.jvm.loader.ByteCodeIterator; public class Method { + private int accessFlag; private int nameIndex; private int descriptorIndex; @@ -44,8 +48,47 @@ public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorInd +public String toString() { + + ConstantPool pool = this.clzFile.getConstantPool(); + StringBuilder buffer = new StringBuilder(); + + String name = ((UTF8Info)pool.getConstantInfo(this.nameIndex)).getValue(); + + String desc = ((UTF8Info)pool.getConstantInfo(this.descriptorIndex)).getValue(); + + buffer.append(name).append(":").append(desc).append("\n"); + + buffer.append(this.codeAttr.toString(pool)); + + return buffer.toString(); + } + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ - return null; + int accessFlag = iter.nextU2ToInt(); + int nameIndex = iter.nextU2ToInt(); + int descIndex = iter.nextU2ToInt(); + int attribCount = iter.nextU2ToInt(); + + + Method m = new Method(clzFile, accessFlag, nameIndex, descIndex); + + for( int j=1; j<= attribCount; j++){ + + int attrNameIndex = iter.nextU2ToInt(); + String attrName = clzFile.getConstantPool().getUTF8String(attrNameIndex); + iter.back(2); + + if(AttributeInfo.CODE.equalsIgnoreCase(attrName)){ + CodeAttr codeAttr = CodeAttr.parse(clzFile, iter); + m.setCodeAttr(codeAttr); + } else{ + throw new RuntimeException("only CODE attribute is implemented , please implement the "+ attrName); + } + + } + + return m ; } } diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixExpr.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixExpr.java new file mode 100644 index 0000000000..74e9474439 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixExpr.java @@ -0,0 +1,14 @@ +package com.github.chaoswang.learning.java.stack.expr; + +public class InfixExpr { + String expr = null; + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + + return 0.0f; + } +} diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassFileloaderTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassFileloaderTest.java index 3694a31b59..2166214272 100644 --- a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassFileloaderTest.java +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassFileloaderTest.java @@ -20,7 +20,7 @@ public class ClassFileloaderTest { - private static final String FULL_QUALIFIED_CLASS_NAME = "com/github/chaoswang/learning/java/jvm/EmployeeV1"; + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; // static String path1 = "E:\\workspace_jee\\coding2017\\target\\test-classes"; static String path1 = "D:\\project\\workspace_1\\d-learning\\target\\test-classes"; static String path2 = "C:\temp"; @@ -29,7 +29,7 @@ public class ClassFileloaderTest { static { ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path1); - String className = "com.github.chaoswang.learning.java.jvm.EmployeeV1"; + String className = "EmployeeV1"; clzFile = loader.loadClass(className); clzFile.print(); @@ -67,7 +67,7 @@ public void testClassFileLength() { byte[] byteCodes = loader.readBinaryCode(className); // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 - Assert.assertEquals(1086, byteCodes.length); + Assert.assertEquals(1056, byteCodes.length); } @@ -75,7 +75,7 @@ public void testClassFileLength() { public void testMagicNumber() { ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path1); - String className = "com.github.chaoswang.learning.java.jvm.EmployeeV1"; + String className = "EmployeeV1"; byte[] byteCodes = loader.readBinaryCode(className); byte[] codes = new byte[] { byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3] }; diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassInfo.txt b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassInfo.txt new file mode 100644 index 0000000000..a1681e82b4 --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassInfo.txt @@ -0,0 +1,162 @@ +Classfile /D:/project/workspace_1/d-learning/target/test-classes/EmployeeV1.class + Last modified 2017-4-14; size 1056 bytes + MD5 checksum 8454b8999ccc9a2ae26a405d47558825 + Compiled from "EmployeeV1.java" +public class com.coderising.jvm.test.EmployeeV1 + minor version: 0 + major version: 52 + flags: ACC_PUBLIC, ACC_SUPER +Constant pool: + #1 = Class #2 // com/coderising/jvm/test/EmployeeV1 + #2 = Utf8 com/coderising/jvm/test/EmployeeV1 + #3 = Class #4 // java/lang/Object + #4 = Utf8 java/lang/Object + #5 = Utf8 name + #6 = Utf8 Ljava/lang/String; + #7 = Utf8 age + #8 = Utf8 I + #9 = Utf8 + #10 = Utf8 (Ljava/lang/String;I)V + #11 = Utf8 Code + #12 = Methodref #3.#13 // java/lang/Object."":()V + #13 = NameAndType #9:#14 // "":()V + #14 = Utf8 ()V + #15 = Fieldref #1.#16 // com/coderising/jvm/test/EmployeeV1.name:Ljava/lang/String; + #16 = NameAndType #5:#6 // name:Ljava/lang/String; + #17 = Fieldref #1.#18 // com/coderising/jvm/test/EmployeeV1.age:I + #18 = NameAndType #7:#8 // age:I + #19 = Utf8 LineNumberTable + #20 = Utf8 LocalVariableTable + #21 = Utf8 this + #22 = Utf8 Lcom/coderising/jvm/test/EmployeeV1; + #23 = Utf8 setName + #24 = Utf8 (Ljava/lang/String;)V + #25 = Utf8 setAge + #26 = Utf8 (I)V + #27 = Utf8 sayHello + #28 = Fieldref #29.#31 // java/lang/System.out:Ljava/io/PrintStream; + #29 = Class #30 // java/lang/System + #30 = Utf8 java/lang/System + #31 = NameAndType #32:#33 // out:Ljava/io/PrintStream; + #32 = Utf8 out + #33 = Utf8 Ljava/io/PrintStream; + #34 = String #35 // Hello , this is class Employee + #35 = Utf8 Hello , this is class Employee + #36 = Methodref #37.#39 // java/io/PrintStream.println:(Ljava/lang/String;)V + #37 = Class #38 // java/io/PrintStream + #38 = Utf8 java/io/PrintStream + #39 = NameAndType #40:#24 // println:(Ljava/lang/String;)V + #40 = Utf8 println + #41 = Utf8 main + #42 = Utf8 ([Ljava/lang/String;)V + #43 = String #44 // Andy + #44 = Utf8 Andy + #45 = Methodref #1.#46 // com/coderising/jvm/test/EmployeeV1."":(Ljava/lang/String;I)V + #46 = NameAndType #9:#10 // "":(Ljava/lang/String;I)V + #47 = Methodref #1.#48 // com/coderising/jvm/test/EmployeeV1.sayHello:()V + #48 = NameAndType #27:#14 // sayHello:()V + #49 = Utf8 args + #50 = Utf8 [Ljava/lang/String; + #51 = Utf8 p + #52 = Utf8 SourceFile + #53 = Utf8 EmployeeV1.java +{ + public com.coderising.jvm.test.EmployeeV1(java.lang.String, int); + descriptor: (Ljava/lang/String;I)V + flags: ACC_PUBLIC + Code: + stack=2, locals=3, args_size=3 + 0: aload_0 + 1: invokespecial #12 // Method java/lang/Object."":()V + 4: aload_0 + 5: aload_1 + 6: putfield #15 // Field name:Ljava/lang/String; + 9: aload_0 + 10: iload_2 + 11: putfield #17 // Field age:I + 14: return + LineNumberTable: + line 9: 0 + line 10: 4 + line 11: 9 + line 12: 14 + LocalVariableTable: + Start Length Slot Name Signature + 0 15 0 this Lcom/coderising/jvm/test/EmployeeV1; + 0 15 1 name Ljava/lang/String; + 0 15 2 age I + + public void setName(java.lang.String); + descriptor: (Ljava/lang/String;)V + flags: ACC_PUBLIC + Code: + stack=2, locals=2, args_size=2 + 0: aload_0 + 1: aload_1 + 2: putfield #15 // Field name:Ljava/lang/String; + 5: return + LineNumberTable: + line 15: 0 + line 16: 5 + LocalVariableTable: + Start Length Slot Name Signature + 0 6 0 this Lcom/coderising/jvm/test/EmployeeV1; + 0 6 1 name Ljava/lang/String; + + public void setAge(int); + descriptor: (I)V + flags: ACC_PUBLIC + Code: + stack=2, locals=2, args_size=2 + 0: aload_0 + 1: iload_1 + 2: putfield #17 // Field age:I + 5: return + LineNumberTable: + line 18: 0 + line 19: 5 + LocalVariableTable: + Start Length Slot Name Signature + 0 6 0 this Lcom/coderising/jvm/test/EmployeeV1; + 0 6 1 age I + + public void sayHello(); + descriptor: ()V + flags: ACC_PUBLIC + Code: + stack=2, locals=1, args_size=1 + 0: getstatic #28 // Field java/lang/System.out:Ljava/io/PrintStream; + 3: ldc #34 // String Hello , this is class Employee + 5: invokevirtual #36 // Method java/io/PrintStream.println:(Ljava/lang/String;)V + 8: return + LineNumberTable: + line 21: 0 + line 22: 8 + LocalVariableTable: + Start Length Slot Name Signature + 0 9 0 this Lcom/coderising/jvm/test/EmployeeV1; + + public static void main(java.lang.String[]); + descriptor: ([Ljava/lang/String;)V + flags: ACC_PUBLIC, ACC_STATIC + Code: + stack=4, locals=2, args_size=1 + 0: new #1 // class com/coderising/jvm/test/EmployeeV1 + 3: dup + 4: ldc #43 // String Andy + 6: bipush 29 + 8: invokespecial #45 // Method "":(Ljava/lang/String;I)V + 11: astore_1 + 12: aload_1 + 13: invokevirtual #47 // Method sayHello:()V + 16: return + LineNumberTable: + line 24: 0 + line 25: 12 + line 27: 16 + LocalVariableTable: + Start Length Slot Name Signature + 0 17 0 args [Ljava/lang/String; + 12 5 1 p Lcom/coderising/jvm/test/EmployeeV1; +} +SourceFile: "EmployeeV1.java" diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/InfixExprTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/InfixExprTest.java new file mode 100644 index 0000000000..613b2d50b6 --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/InfixExprTest.java @@ -0,0 +1,48 @@ +package com.github.chaoswang.learning.java.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); + } + + } + +} From deac79b38ba4b816722320108a91ab3b676321bc Mon Sep 17 00:00:00 2001 From: 10094714 Date: Wed, 3 May 2017 17:28:33 +0800 Subject: [PATCH 2/4] datastruct practise --- .../learning/java/queue/CircleQueue.java | 42 +++++++++ .../learning/java/queue/Josephus.java | 18 ++++ .../chaoswang/learning/java/queue/Queue.java | 92 +++++++++++++++++++ .../java/queue/QueueWithTwoStacks.java | 33 +++++++ .../learning/java/stack/expr/InfixExpr.java | 28 +++++- .../java/stack/expr/InfixToPostfix.java | 67 ++++++++++++++ .../learning/java/stack/expr/PostfixExpr.java | 43 +++++++++ .../learning/java/stack/expr/PrefixExpr.java | 41 +++++++++ .../learning/java/stack/expr/Token.java | 53 +++++++++++ .../learning/java/stack/expr/TokenParser.java | 44 +++++++++ .../java/stack/operation/AddImpl.java | 10 ++ .../java/stack/operation/DivideImpl.java | 15 +++ .../java/stack/operation/MinusImpl.java | 10 ++ .../java/stack/operation/MultiplyImpl.java | 10 ++ .../java/stack/operation/Operation.java | 5 + .../stack/operation/OperationFactory.java | 18 ++++ .../learning/java/queue/JosephusTest.java | 14 +++ .../java/stack/expr/InfixExprTest.java | 12 --- .../java/stack/expr/PostfixExprTest.java | 30 ++++++ .../java/stack/expr/PrefixExprTest.java | 36 ++++++++ .../java/stack/expr/TokenParserTest.java | 28 ++++++ 21 files changed, 636 insertions(+), 13 deletions(-) create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/CircleQueue.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/Josephus.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/Queue.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/QueueWithTwoStacks.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixToPostfix.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/PostfixExpr.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/PrefixExpr.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/Token.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/TokenParser.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/AddImpl.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/DivideImpl.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/MinusImpl.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/MultiplyImpl.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/Operation.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/OperationFactory.java create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/queue/JosephusTest.java create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/PostfixExprTest.java create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/PrefixExprTest.java create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/TokenParserTest.java diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/CircleQueue.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/CircleQueue.java new file mode 100644 index 0000000000..fcdf73b955 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/CircleQueue.java @@ -0,0 +1,42 @@ +package com.github.chaoswang.learning.java.queue; + +/** + * 每次在队尾插入一个元素是,rear增1;每次在队头删除一个元素时,front增1。 + * 随着插入和删除操作的进行,队列元素的个数不断变化,队列所占的存储空间也在为队列结构所分配的连续空间中移动。 + * 当front=rear时,队列中没有任何元素,称为空队列。 + * 当rear增加到指向分配的连续空间之外时,队列无法再插入新元素,但这时往往还有大量可用空间未被占用, + * 这些空间是已经出队的队列元素曾经占用过得存储单元。 + * [(front,rear), , , ] 1.初始状态,四个空间为空,front和rear指向同一个位置 + * [A(front) , B , C, (rear)] 2.插入A,B,C三个元素 + * [ , B(front), C, (rear)] 3.移除A元素 + * [ , , , (front,rear)] 3.移除B,C元素 + * 用数组实现循环队列 + */ +public class CircleQueue { + + private final static int DEFAULT_SIZE = 10; + + //用数组来保存循环队列的元素 + private Object[] elementData = new Object[DEFAULT_SIZE] ; + + //队头 + private int front = 0; + //队尾 + private int rear = 0; + + public boolean isEmpty() { + return false; + } + + public int size() { + return -1; + } + + public void enQueue(E data) { + + } + + public E deQueue() { + return null; + } +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/Josephus.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/Josephus.java new file mode 100644 index 0000000000..a176bb653d --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/Josephus.java @@ -0,0 +1,18 @@ +package com.github.chaoswang.learning.java.queue; + +import java.util.List; + +/** + * 用Queue来实现Josephus问题 + * 在这个古老的问题当中, N个深陷绝境的人一致同意用这种方式减少生存人数: N个人围成一圈(位置记为0到N-1), + * 并且从第一个人报数, 报到M的人会被杀死, 直到最后一个人留下来 + * 该方法返回一个List, 包含了被杀死人的次序 + * + */ +public class Josephus { + + public static List execute(int n, int m){ + return null; + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/Queue.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/Queue.java new file mode 100644 index 0000000000..ce32ad807b --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/Queue.java @@ -0,0 +1,92 @@ +package com.github.chaoswang.learning.java.queue; + +import java.util.NoSuchElementException; + + +public class Queue { + private int size = 0; + private int capacitySize; + private OneElement first = null; + private OneElement last = null;//可以改为用自己的LinkedList实现 + + public Queue(int capacitySize){ + this.capacitySize = capacitySize; + } + + //插入队尾 队列满时抛异常 + public void add(E element){ + if(size+1 > capacitySize){ + throw new IllegalStateException("over capacity."); + } + addLast(element); + } + + //插入队尾 不抛异常,会返回是否插入成功 + public boolean offer(E element){ + if(size+1 > capacitySize){ + return false; + } + addLast(element); + return true; + } + + private void addLast(E element){ + OneElement tmp = new OneElement(element, null); + if(last == null){ + first = tmp; + }else{ + last.next = tmp;; + } + last = tmp; + size++; + } + + //移除队头元素,队列为空时抛异常 + public E remove(){ + if(size == 0){ + throw new NoSuchElementException(); + } + return removeFirst(); + } + + //移除队头元素,队列为空时返回null,所以queue一般不让插入null元素 + public E poll(){ + if(size == 0){ + return null; + } + return removeFirst(); + } + + private E removeFirst(){ + OneElement tmp = first; + first = first.next; + size--; + return tmp.element; + } + + //返回队头元素,但是不移除,队列为空时抛异常 + public E element(){ + if(size == 0){ + throw new NoSuchElementException(); + } + return first.element; + } + + //返回队头元素,但是不移除,队列为空时返回null + public E peek(){ + if(size == 0){ + return null; + } + return first.element; + } + + private class OneElement{ + private E element = null; + private OneElement next = null; + + public OneElement(E element, OneElement next) { + this.element = element; + this.next = next; + } + } +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/QueueWithTwoStacks.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/QueueWithTwoStacks.java new file mode 100644 index 0000000000..106764a6fc --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/queue/QueueWithTwoStacks.java @@ -0,0 +1,33 @@ +package com.github.chaoswang.learning.java.queue; + +import java.util.Stack; + +/** + * 用两个栈来实现一个队列 + */ +public class QueueWithTwoStacks { + private Stack stack1; + private Stack stack2; + + public QueueWithTwoStacks() { + stack1 = new Stack(); + stack2 = new Stack(); + } + + public boolean isEmpty() { + return false; + } + + public int size() { + return -1; + } + + public void enQueue(E item) { + + } + + public E deQueue() { + return null; + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixExpr.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixExpr.java index 74e9474439..195ebb3380 100644 --- a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixExpr.java +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixExpr.java @@ -1,5 +1,18 @@ package com.github.chaoswang.learning.java.stack.expr; +import java.util.List; +import java.util.Stack; + +import com.github.chaoswang.learning.java.stack.operation.Operation; +import com.github.chaoswang.learning.java.stack.operation.OperationFactory; + +/** + * 中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。 + * 中缀表达式是人们常用的算术表示方法。虽然人的大脑很容易理解与分析中缀表达式, + * 但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式, + * 然后再进行求值。对计算机来说,计算前缀或后缀表达式的值非常简单。 + * + */ public class InfixExpr { String expr = null; @@ -8,7 +21,20 @@ public InfixExpr(String expr) { } public float evaluate() { + List tokens = InfixToPostfix.convert(expr); - return 0.0f; + Stack stack = new Stack(); + for(Token token : tokens){ + if(token.isNumber()){ + stack.push(Float.parseFloat(token.value)); + } + if(token.isOperator()){ + float num1 = stack.pop(); + float num2 = stack.pop(); + Operation op = OperationFactory.getOperation(token.value); + stack.push(op.doOperation(num2, num1)); + } + } + return stack.pop(); } } diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixToPostfix.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixToPostfix.java new file mode 100644 index 0000000000..3f0d907200 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/InfixToPostfix.java @@ -0,0 +1,67 @@ +package com.github.chaoswang.learning.java.stack.expr; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +/** + * 将中缀表达式转换为后缀表达式: +(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2; +(2) 从左至右扫描中缀表达式; +(3) 遇到操作数时,将其压入S2; +(4) 遇到运算符时,比较其与S1栈顶运算符的优先级: +(4-1) 如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈; +(4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况); +(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较; +(5) 遇到括号时: +(5-1) 如果是左括号“(”,则直接压入S1; +(5-2) 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃; +(6) 重复步骤(2)至(5),直到表达式的最右边; +(7) 将S1中剩余的运算符依次弹出并压入S2; +(8) 依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。 + * + */ +public class InfixToPostfix { + public static List convert(String expr) { + Stack s1 = new Stack(); + Stack s2 = new Stack(); + List tokens = new TokenParser().parse(expr); + System.out.println(tokens); + for(Token token : tokens){ + if(token.isNumber()){ + s2.push(token); + }else if(token.isOperator()){ + int size1 = s1.size(); + for(int i=0;i(); + int size2 = s2.size(); + for(int i=0;i tokens = parser.parse(expr); + Stack stack = new Stack(); + for(Token token : tokens){ + if(token.isNumber()){ + stack.push(Float.parseFloat(token.value)); + } + if(token.isOperator()){ + float num1 = stack.pop(); + float num2 = stack.pop(); + Operation op = OperationFactory.getOperation(token.value); + stack.push(op.doOperation(num2, num1)); + } + } + return stack.pop(); + } + +} \ No newline at end of file diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/PrefixExpr.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/PrefixExpr.java new file mode 100644 index 0000000000..269fcdd36d --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/PrefixExpr.java @@ -0,0 +1,41 @@ +package com.github.chaoswang.learning.java.stack.expr; + +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +import com.github.chaoswang.learning.java.stack.operation.Operation; +import com.github.chaoswang.learning.java.stack.operation.OperationFactory; + +/** + * 从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数, + * 用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈; + * 重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。 + * + */ +public class PrefixExpr { + String expr = null; + + public PrefixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + TokenParser parser = new TokenParser(); + List tokens = parser.parse(expr); + Collections.reverse(tokens); + Stack stack = new Stack(); + for(Token token : tokens){ + if(token.isNumber()){ + stack.push(Float.parseFloat(token.value)); + } + if(token.isOperator()){ + float num1 = stack.pop(); + float num2 = stack.pop(); + Operation op = OperationFactory.getOperation(token.value); + stack.push(op.doOperation(num1, num2)); + } + } + return stack.pop(); + } +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/Token.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/Token.java new file mode 100644 index 0000000000..1d620459ed --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/Token.java @@ -0,0 +1,53 @@ +package com.github.chaoswang.learning.java.stack.expr; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Token在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。 + */ +class Token { + public static final List OPERATORS = Arrays.asList("+", "-", "*", "/"); + private static final Map priorities = new HashMap<>(); + static { + priorities.put("+", 1); + priorities.put("-", 1); + priorities.put("*", 2); + priorities.put("/", 2); + } + static final int OPERATOR = 1; + static final int NUMBER = 2; + String value; + int type; + + public Token(int type, String value) { + this.type = type; + this.value = value; + } + + public boolean isNumber() { + return type == NUMBER; + } + + public boolean isOperator() { + return type == OPERATOR; + } + + public int getIntValue() { + return Integer.valueOf(value).intValue(); + } + + public String toString() { + return value; + } + + public boolean hasHigherPriority(Token t) { + if (!this.isOperator() && !t.isOperator()) { + throw new RuntimeException("numbers can't compare priority"); + } + return priorities.get(this.value) - priorities.get(t.value) > 0; + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/TokenParser.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/TokenParser.java new file mode 100644 index 0000000000..4f0aebf05b --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/expr/TokenParser.java @@ -0,0 +1,44 @@ +package com.github.chaoswang.learning.java.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 (isOperator(c)) { + Token t = new Token(Token.OPERATOR, String.valueOf(c)); + tokens.add(t); + i++; + } else if (Character.isDigit(c)) { + int nextOperatorIndex = indexOfNextOperator(i, expr); + String value = expr.substring(i, nextOperatorIndex); + Token t = new Token(Token.NUMBER, value); + tokens.add(t); + i = nextOperatorIndex; + } else { + System.out.println("char :[" + c + "] is not number or operator,ignore"); + i++; + } + } + return tokens; + } + + private int indexOfNextOperator(int i, String expr) { + while (Character.isDigit(expr.charAt(i))) { + i++; + if (i == expr.length()) { + break; + } + } + return i; + } + + private boolean isOperator(char c) { + String sc = String.valueOf(c); + return Token.OPERATORS.contains(sc); + } +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/AddImpl.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/AddImpl.java new file mode 100644 index 0000000000..4b2cd0782a --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/AddImpl.java @@ -0,0 +1,10 @@ +package com.github.chaoswang.learning.java.stack.operation; + +public class AddImpl implements Operation{ + + @Override + public float doOperation(float a, float b) { + return a + b; + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/DivideImpl.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/DivideImpl.java new file mode 100644 index 0000000000..eee23d843e --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/DivideImpl.java @@ -0,0 +1,15 @@ +package com.github.chaoswang.learning.java.stack.operation; + +public class DivideImpl implements Operation{ + + @Override + public float doOperation(float a, float b) { + try { + return a / b; + } catch (ArithmeticException e) { + e.printStackTrace(); + } + return 1; + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/MinusImpl.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/MinusImpl.java new file mode 100644 index 0000000000..eea672294f --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/MinusImpl.java @@ -0,0 +1,10 @@ +package com.github.chaoswang.learning.java.stack.operation; + +public class MinusImpl implements Operation{ + + @Override + public float doOperation(float a, float b) { + return a - b; + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/MultiplyImpl.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/MultiplyImpl.java new file mode 100644 index 0000000000..868fe47fd0 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/MultiplyImpl.java @@ -0,0 +1,10 @@ +package com.github.chaoswang.learning.java.stack.operation; + +public class MultiplyImpl implements Operation{ + + @Override + public float doOperation(float a, float b) { + return a * b; + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/Operation.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/Operation.java new file mode 100644 index 0000000000..87d5056645 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/Operation.java @@ -0,0 +1,5 @@ +package com.github.chaoswang.learning.java.stack.operation; + +public interface Operation { + float doOperation(float a, float b); +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/OperationFactory.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/OperationFactory.java new file mode 100644 index 0000000000..463cc6bf09 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/operation/OperationFactory.java @@ -0,0 +1,18 @@ +package com.github.chaoswang.learning.java.stack.operation; + +import java.util.HashMap; +import java.util.Map; + +public class OperationFactory { + private static final Map operations = new HashMap<>(); + static { + operations.put("+", new AddImpl()); + operations.put("-", new MinusImpl()); + operations.put("*", new MultiplyImpl()); + operations.put("/", new DivideImpl()); + } + + public static Operation getOperation(String operator){ + return operations.get(operator); + } +} diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/queue/JosephusTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/queue/JosephusTest.java new file mode 100644 index 0000000000..653e5535a7 --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/queue/JosephusTest.java @@ -0,0 +1,14 @@ +package com.github.chaoswang.learning.java.queue; + +import org.junit.Assert; +import org.junit.Test; + +public class JosephusTest { + @Test + public void testExecute() { + + Assert.assertEquals("[1, 3, 5, 0, 4, 2, 6]", Josephus.execute(7, 2).toString()); + + } + +} diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/InfixExprTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/InfixExprTest.java index 613b2d50b6..9766b438a1 100644 --- a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/InfixExprTest.java +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/InfixExprTest.java @@ -1,24 +1,12 @@ package com.github.chaoswang.learning.java.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); diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/PostfixExprTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/PostfixExprTest.java new file mode 100644 index 0000000000..e47795f06f --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/PostfixExprTest.java @@ -0,0 +1,30 @@ +package com.github.chaoswang.learning.java.stack.expr; + +import org.junit.Assert; +import org.junit.Test; + +/** + * 从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数, 用运算符对它们做相应的计算(次顶元素 op 栈顶元素),并将结果入栈; + * 重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。 + */ +public class PostfixExprTest { + @Test + public void testEvaluate() { + //下面的大括号仅仅只是起划分区域作用 + { // 6*(5+(2+3)*8+3) + PostfixExpr expr = new PostfixExpr("6 5 2 3 + 8 * + 3 + *"); + Assert.assertEquals(288, expr.evaluate(), 0.0f); + } + { + // 9+(3-1)*3+10/2 + PostfixExpr expr = new PostfixExpr("9 3 1-3*+ 10 2/+"); + Assert.assertEquals(20, expr.evaluate(), 0.0f); + } + { + // 10-2*3+50 + PostfixExpr expr = new PostfixExpr("10 2 3 * - 50 +"); + Assert.assertEquals(54, expr.evaluate(), 0.0f); + } + } + +} diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/PrefixExprTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/PrefixExprTest.java new file mode 100644 index 0000000000..f0ac3c4e93 --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/PrefixExprTest.java @@ -0,0 +1,36 @@ +package com.github.chaoswang.learning.java.stack.expr; + +import org.junit.Assert; +import org.junit.Test; + +/** + * 从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数, + * 用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈; + * 重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。 + * + */ +public class PrefixExprTest { + @Test + public void testEvaluate() { + { + // 2*3+4*5 + PrefixExpr expr = new PrefixExpr("+ * 2 3* 4 5"); + Assert.assertEquals(26, expr.evaluate(),0.001f); + } + { + // 4*2 + 6+9*2/3 -8 + PrefixExpr expr = new PrefixExpr("-++6/*2 9 3 * 4 2 8"); + Assert.assertEquals(12, expr.evaluate(),0.001f); + } + { + //(3+4)*5-6 + PrefixExpr expr = new PrefixExpr("- * + 3 4 5 6"); + Assert.assertEquals(29, expr.evaluate(),0.001f); + } + { + //1+((2+3)*4)-5 + PrefixExpr expr = new PrefixExpr("- + 1 * + 2 3 4 5"); + Assert.assertEquals(16, expr.evaluate(),0.001f); + } + } +} diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/TokenParserTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/TokenParserTest.java new file mode 100644 index 0000000000..0d98783447 --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/stack/expr/TokenParserTest.java @@ -0,0 +1,28 @@ +package com.github.chaoswang.learning.java.stack.expr; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +public class TokenParserTest { + @Test + public void test() { + + TokenParser parser = new TokenParser(); + List tokens = parser.parse("300*20+12*5-20/4"); + + Assert.assertEquals(300, tokens.get(0).getIntValue()); + Assert.assertEquals("*", tokens.get(1).toString()); + Assert.assertEquals(20, tokens.get(2).getIntValue()); + Assert.assertEquals("+", tokens.get(3).toString()); + Assert.assertEquals(12, tokens.get(4).getIntValue()); + Assert.assertEquals("*", tokens.get(5).toString()); + Assert.assertEquals(5, tokens.get(6).getIntValue()); + Assert.assertEquals("-", tokens.get(7).toString()); + Assert.assertEquals(20, tokens.get(8).getIntValue()); + Assert.assertEquals("/", tokens.get(9).toString()); + Assert.assertEquals(4, tokens.get(10).getIntValue()); + } + +} From 4cc3cc7277965b21b5abcc19d7c88287d904ef7e Mon Sep 17 00:00:00 2001 From: chaoswang Date: Wed, 3 May 2017 21:38:01 +0800 Subject: [PATCH 3/4] StackUtil --- .../learning/java/stack/StackUtil.java | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/StackUtil.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/StackUtil.java index 7f2c30d1f1..03ba7d46ac 100644 --- a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/StackUtil.java +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/StackUtil.java @@ -46,10 +46,9 @@ public static void remove(Stack s, Object o) { Stack tmpStack = new Stack(); while(!s.empty()){ Integer poped = s.pop(); - if(o.equals(poped)){ - break; + if(!o.equals(poped)){ + tmpStack.push(poped); } - tmpStack.push(poped); } while(!tmpStack.empty()){ s.push(tmpStack.pop()); @@ -89,7 +88,7 @@ public static Object[] getTop(Stack s, int len) { * @param s * @return */ - public static boolean isValidPairs(String s) { + public static boolean isValidPairs_bad(String s) { Map map = new HashMap(); map.put(')', '('); map.put(']', '['); @@ -120,5 +119,38 @@ public static boolean isValidPairs(String s) { } return true; } - + + public static boolean isValidPairs(String s){ + Stack stack = new Stack(); + for(int i=0;i Date: Sun, 18 Jun 2017 21:28:58 +0800 Subject: [PATCH 4/4] =?UTF-8?q?solid=E5=8E=9F=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../learning/java/ood/srp/Configuration.java | 23 +++ .../java/ood/srp/ConfigurationKeys.java | 8 + .../learning/java/ood/srp/DBUtil.java | 24 +++ .../learning/java/ood/srp/MailUtil.java | 15 ++ .../learning/java/ood/srp/PromotionMail.java | 158 ++++++++++++++++++ .../java/ood/srp/product_promotion.txt | 4 + .../java/ood/srp/refactor/Product.java | 5 + .../java/ood/srp/refactor/SmtpHost.java | 22 +++ .../learning/java/ood/srp/refactor/User.java | 5 + 9 files changed, 264 insertions(+) create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/Configuration.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/ConfigurationKeys.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/DBUtil.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/MailUtil.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/PromotionMail.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/product_promotion.txt create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/Product.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/SmtpHost.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/User.java diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/Configuration.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/Configuration.java new file mode 100644 index 0000000000..d34015a7b5 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/Configuration.java @@ -0,0 +1,23 @@ +package com.github.chaoswang.learning.java.ood.srp; + +import java.util.HashMap; +import java.util.Map; + +public class Configuration { + + static Map configurations = new HashMap<>(); + static{ + configurations.put(ConfigurationKeys.SMTP_SERVER, "smtp.163.com"); + configurations.put(ConfigurationKeys.ALT_SMTP_SERVER, "smtp1.163.com"); + configurations.put(ConfigurationKeys.EMAIL_ADMIN, "admin@company.com"); + } + /** + * 应该从配置文件读, 但是这里简化为直接从一个map 中去读 + * @param key + * @return + */ + public String getProperty(String key) { + return configurations.get(key); + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/ConfigurationKeys.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/ConfigurationKeys.java new file mode 100644 index 0000000000..0c08da1202 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/ConfigurationKeys.java @@ -0,0 +1,8 @@ +package com.github.chaoswang.learning.java.ood.srp; + +public class ConfigurationKeys { + + public static final String SMTP_SERVER = "smtp.server"; + public static final String ALT_SMTP_SERVER = "alt.smtp.server"; + public static final String EMAIL_ADMIN = "email.admin"; +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/DBUtil.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/DBUtil.java new file mode 100644 index 0000000000..0e1251487f --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/DBUtil.java @@ -0,0 +1,24 @@ +package com.github.chaoswang.learning.java.ood.srp; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class DBUtil { + /** + * 应该从数据库读, 但是简化为直接生成。 + * @param sql + * @return + */ + public static List query(String sql){ + + List userList = new ArrayList(); + for (int i = 1; i <= 3; i++) { + HashMap userInfo = new HashMap(); + userInfo.put("NAME", "User" + i); + userInfo.put("EMAIL", "aa@bb.com"); + userList.add(userInfo); + } + return userList; + } +} \ No newline at end of file diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/MailUtil.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/MailUtil.java new file mode 100644 index 0000000000..e3da534ee2 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/MailUtil.java @@ -0,0 +1,15 @@ +package com.github.chaoswang.learning.java.ood.srp; + +public class MailUtil { + + public static void sendEmail(String toAddress, String fromAddress, String subject, String message, String smtpHost, + boolean debug) { + // 假装发了一封邮件 + StringBuilder buffer = new StringBuilder(); + buffer.append("From:").append(fromAddress).append("\n"); + buffer.append("To:").append(toAddress).append("\n"); + buffer.append("Subject:").append(subject).append("\n"); + buffer.append("Content:").append(message).append("\n"); + System.out.println(buffer.toString()); + } +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/PromotionMail.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/PromotionMail.java new file mode 100644 index 0000000000..c4564295a4 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/PromotionMail.java @@ -0,0 +1,158 @@ +package com.github.chaoswang.learning.java.ood.srp; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +public class PromotionMail { + + protected String sendMailQuery = null; + + protected String smtpHost = null; + protected String altSmtpHost = null; + protected String fromAddress = null; + protected String toAddress = null; + protected String subject = null; + protected String message = null; + + protected String productID = null; + protected String productDesc = null; + + private static Configuration config; + + private static final String NAME_KEY = "NAME"; + private static final String EMAIL_KEY = "EMAIL"; + + public static void main(String[] args) throws Exception { + File f = new File("C:\\coderising\\workspace_ds\\ood-example\\src\\product_promotion.txt"); + boolean emailDebug = false; + PromotionMail pe = new PromotionMail(f, emailDebug); + } + + public PromotionMail(File file, boolean mailDebug) throws Exception { + + // 读取配置文件, 文件中只有一行用空格隔开, 例如 P8756 iPhone8 + readFile(file); + + config = new Configuration(); + + setSMTPHost(); + setAltSMTPHost(); + + setFromAddress(); + + setLoadQuery(); + + sendEMails(mailDebug, loadMailingList()); + + } + + protected void setProductID(String productID) { + this.productID = productID; + + } + + protected String getproductID() { + return productID; + } + + protected void setLoadQuery() throws Exception { + + sendMailQuery = "Select name from subscriptions " + "where product_id= '" + productID + "' " + + "and send_mail=1 "; + + System.out.println("loadQuery set"); + } + + protected void setSMTPHost() { + smtpHost = config.getProperty(ConfigurationKeys.SMTP_SERVER); + } + + protected void setAltSMTPHost() { + altSmtpHost = config.getProperty(ConfigurationKeys.ALT_SMTP_SERVER); + + } + + protected void setFromAddress() { + fromAddress = config.getProperty(ConfigurationKeys.EMAIL_ADMIN); + } + + protected void setMessage(HashMap userInfo) throws IOException { + + String name = (String) userInfo.get(NAME_KEY); + + subject = "您关注的产品降价了"; + message = "尊敬的 " + name + ", 您关注的产品 " + productDesc + " 降价了,欢迎购买!"; + + } + + protected void readFile(File file) throws IOException // @02C + { + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(file)); + String temp = br.readLine(); + String[] data = temp.split(" "); + + setProductID(data[0]); + setProductDesc(data[1]); + + System.out.println("产品ID = " + productID + "\n"); + System.out.println("产品描述 = " + productDesc + "\n"); + + } catch (IOException e) { + throw new IOException(e.getMessage()); + } finally { + br.close(); + } + } + + private void setProductDesc(String desc) { + this.productDesc = desc; + } + + protected void configureEMail(HashMap userInfo) throws IOException { + toAddress = (String) userInfo.get(EMAIL_KEY); + if (toAddress.length() > 0) + setMessage(userInfo); + } + + protected List loadMailingList() throws Exception { + return DBUtil.query(this.sendMailQuery); + } + + protected void sendEMails(boolean debug, List mailingList) throws IOException { + + System.out.println("开始发送邮件"); + + if (mailingList != null) { + Iterator iter = mailingList.iterator(); + while (iter.hasNext()) { + configureEMail((HashMap) iter.next()); + try { + if (toAddress.length() > 0) + MailUtil.sendEmail(toAddress, fromAddress, subject, message, smtpHost, debug); + } catch (Exception e) { + + try { + MailUtil.sendEmail(toAddress, fromAddress, subject, message, altSmtpHost, debug); + + } catch (Exception e2) { + System.out.println("通过备用 SMTP服务器发送邮件失败: " + e2.getMessage()); + } + } + } + + } + + else { + System.out.println("没有邮件发送"); + + } + + } +} \ No newline at end of file diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/product_promotion.txt b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/product_promotion.txt new file mode 100644 index 0000000000..b7a974adb3 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/product_promotion.txt @@ -0,0 +1,4 @@ +P8756 iPhone8 +P3946 XiaoMi10 +P8904 Oppo_R15 +P4955 Vivo_X20 \ No newline at end of file diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/Product.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/Product.java new file mode 100644 index 0000000000..cd0cabef7d --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/Product.java @@ -0,0 +1,5 @@ +package com.github.chaoswang.learning.java.ood.srp.refactor; + +public class Product { + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/SmtpHost.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/SmtpHost.java new file mode 100644 index 0000000000..fd79435ccc --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/SmtpHost.java @@ -0,0 +1,22 @@ +package com.github.chaoswang.learning.java.ood.srp.refactor; + +import com.github.chaoswang.learning.java.ood.srp.Configuration; +import com.github.chaoswang.learning.java.ood.srp.ConfigurationKeys; + +public class SmtpHost { + private String smtpHost = null; + private String altSmtpHost = null; + private String fromAddress = null; + private static Configuration config; + + public SmtpHost(){ + config = new Configuration(); + smtpHost = config.getProperty(ConfigurationKeys.SMTP_SERVER); + altSmtpHost = config.getProperty(ConfigurationKeys.ALT_SMTP_SERVER); + fromAddress = config.getProperty(ConfigurationKeys.EMAIL_ADMIN); + } + + public void sendMail() { + smtpHost = config.getProperty(ConfigurationKeys.SMTP_SERVER); + } +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/User.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/User.java new file mode 100644 index 0000000000..a1e4c19d11 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/ood/srp/refactor/User.java @@ -0,0 +1,5 @@ +package com.github.chaoswang.learning.java.ood.srp.refactor; + +public class User { + +}