diff --git a/group24/1148285693/learning2017/common/src/main/java/me/lzb/common/utils/ByteUtils.java b/group24/1148285693/learning2017/common/src/main/java/me/lzb/common/utils/ByteUtils.java new file mode 100644 index 0000000000..f6586ce761 --- /dev/null +++ b/group24/1148285693/learning2017/common/src/main/java/me/lzb/common/utils/ByteUtils.java @@ -0,0 +1,26 @@ +package me.lzb.common.utils; + +/** + * Created by LZB on 2017/4/14. + */ +public class ByteUtils { + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i + + me.lzb + common + 1.0 + diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayList.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayList.java similarity index 98% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayList.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayList.java index 080aa4f724..af897cd58f 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayList.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayList.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * 简易ArrayList diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayUtil.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayUtil.java similarity index 99% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayUtil.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayUtil.java index de101845aa..eab32c80cc 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayUtil.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayUtil.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; public class ArrayUtil { diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/BinaryTreeNode.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/BinaryTreeNode.java similarity index 97% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/BinaryTreeNode.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/BinaryTreeNode.java index dfcaa60300..88395e3010 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/BinaryTreeNode.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/BinaryTreeNode.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * 左边比父节点小,右边比父节点大 diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/InfixExpr.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/InfixExpr.java new file mode 100644 index 0000000000..e30cc00cc2 --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/InfixExpr.java @@ -0,0 +1,161 @@ +package me.lzb.basic; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Created by LZB on 2017/4/15. + */ +public class InfixExpr { + + + private String expr; + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + + List list = processExpr(); + + Stack symbolStack = new Stack<>(); + Stack numberStack = new Stack<>(); + + boolean calLevel2 = false; + for (Node n : list) { + if (n.isNumber) { + numberStack.push(n.number); + if (calLevel2) { + calculate(symbolStack, numberStack, false); + calLevel2 = false; + } + } else { + symbolStack.push(n.symbol); + + if (n.isLevel2()) { + calLevel2 = true; + } + } + } + + + Stack tn = new Stack<>(); + int nsize = numberStack.size(); + for (int i = 0; i < nsize; i++) { + tn.push(numberStack.pop()); + } + + numberStack = tn; + + + Stack ts = new Stack<>(); + int ssize = symbolStack.size(); + for (int i = 0; i < ssize; i++) { + ts.push(symbolStack.pop()); + } + + symbolStack = ts; + + + while (!symbolStack.isEmpty()) { + calculate(symbolStack, numberStack, true); + } + + + return numberStack.pop(); + } + + + + private List processExpr() { + List list = new ArrayList<>(); + char[] array = this.expr.toCharArray(); + String number = ""; + for (int i = 0; i < array.length; i++) { + if (Character.isDigit(array[i])) { + number = number + String.valueOf(array[i]); + } else { + Node num = new Node(Float.valueOf(number), null, true, -1); + number = ""; + int calLevel = "+-".indexOf(array[i]) >= 0 ? 1 : 2; + Node sym = new Node(0, String.valueOf(array[i]), false, calLevel); + list.add(num); + list.add(sym); + } + } + + Node num = new Node(Float.valueOf(number), null, true, -1); + list.add(num); + return list; + } + + + private void calculate(Stack symbolStack, Stack numberStack, boolean isRe) { + if (symbolStack.isEmpty()) { + return; + } + + + String symbole = symbolStack.pop(); + + float right; + float left; + + if(isRe){ + left = numberStack.pop(); + right = numberStack.pop(); + }else { + right = numberStack.pop(); + left = numberStack.pop(); + } + + + + float r = calculate(symbole, left, right); + + numberStack.push(r); + } + + + private float calculate(String symbol, float left, float right) { + if ("+".equals(symbol)) { + return left + right; + } + + if ("-".equals(symbol)) { + return left - right; + } + + if ("*".equals(symbol)) { + return left * right; + } + + if ("/".equals(symbol)) { + return left / right; + } + + return 0; + } + + + private class Node { + float number; + String symbol; + boolean isNumber; + int calLevel;//加减1,乘除2 + + public Node(float number, String symbol, boolean isNumber, int calLevel) { + this.number = number; + this.symbol = symbol; + this.isNumber = isNumber; + this.calLevel = calLevel; + } + + private boolean isLevel2() { + return calLevel == 2; + } + } + +} diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Iterator.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Iterator.java similarity index 80% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Iterator.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Iterator.java index b65f73b2e3..86e8cae942 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Iterator.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Iterator.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * Created by LZB on 2017/3/11. diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/algorithm/LRUPageFrame.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LRUPageFrame.java similarity index 99% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/algorithm/LRUPageFrame.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LRUPageFrame.java index 1f1d0a36b7..6e0e570ce6 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/algorithm/LRUPageFrame.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LRUPageFrame.java @@ -1,4 +1,4 @@ -package me.lzb.algorithm; +package me.lzb.basic; /** * 用双向链表实现LRU算法 diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/LinkedList.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LinkedList.java similarity index 99% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/LinkedList.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LinkedList.java index f79b7eaf18..268b69bf50 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/LinkedList.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LinkedList.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/List.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/List.java similarity index 86% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/List.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/List.java index 8f6478c49e..df7f30812b 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/List.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/List.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * list接口 diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Queue.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Queue.java similarity index 94% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Queue.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Queue.java index 35dc95f688..08303d3fb5 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Queue.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Queue.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * 先进先出 diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Stack.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Stack.java similarity index 97% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Stack.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Stack.java index 367b7210e6..60785110eb 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Stack.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Stack.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * 先进后出 diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/StackUtil.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/StackUtil.java new file mode 100644 index 0000000000..547eb6105f --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/StackUtil.java @@ -0,0 +1,155 @@ +package me.lzb.basic; + +import java.util.Stack; + +public class StackUtil { + + public static void bad_reverse(Stack s) { + + + } + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + Stack t = new Stack<>(); + for (Integer i : s) { + t.push(i); + } + + s.clear(); + + int size = t.size(); + for (int i = 0; i < size; i++) { + s.push(t.pop()); + } + + } + + public static void addToBottom(Stack s, Integer value) { + Stack t = new Stack<>(); + int size = s.size(); + for (int i = 0; i < size; i++) { + t.push(s.pop()); + } + + s.clear(); + + s.push(value); + + for (int i = 0; i < size; i++) { + s.push(t.pop()); + } + + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s, Object o) { + Stack t = new Stack(); + int size = s.size(); + for (int i = 0; i < size; i++) { + Object ro = s.pop(); + if (!ro.equals(o)) { + t.push(ro); + } + } + + s.clear(); + + int sizet = t.size(); + for (int i = 0; i < sizet; i++) { + s.push(t.pop()); + } + + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param len + * @return + */ + public static Object[] getTop(Stack s, int len) { + Object[] array = new Object[len]; + for (int i = 0; i < len; i++) { + array[i] = s.pop(); + } + + for (int i = len - 1; i >= 0; i--) { + s.push(array[i]); + } + return array; + } + + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + char[] array = s.toCharArray(); + Stack stack = new Stack<>(); + for (int i = 0; i < array.length; i++) { + stack.push(String.valueOf(array[i])); + } + + + int a = -1; + int b = -1; + int c = -1; + + + for (int i = 0; i < array.length; i++) { + String cc = stack.pop(); + + if ("{}".indexOf(cc) >= 0) { + if (a == -1) { + a = i; + } else { + if (stack.size() != a) { + return false; + } + } + } + + if ("[]".indexOf(cc) >= 0) { + + if (b == -1) { + b = i; + } else { + if (stack.size() != b) { + return false; + } + } + + } + + if ("()".indexOf(cc) >= 0) { + + if (c == -1) { + c = i; + } else { + if (stack.size() != c) { + return false; + } + } + + } + + } + return true; + } + + +} diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/ArrayListTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/ArrayListTest.java similarity index 96% rename from group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/ArrayListTest.java rename to group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/ArrayListTest.java index dcb879a948..efcfdbae1d 100644 --- a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/ArrayListTest.java +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/ArrayListTest.java @@ -1,7 +1,7 @@ -package me.lzb.datastructure; +package me.lzb.basic; -import me.lzb.datastructure.ArrayList; -import me.lzb.datastructure.Iterator; +import me.lzb.basic.ArrayList; +import me.lzb.basic.Iterator; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/InfixExprTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/InfixExprTest.java new file mode 100644 index 0000000000..5ca7621354 --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/InfixExprTest.java @@ -0,0 +1,48 @@ +package me.lzb.basic; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class InfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + //InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); + { + InfixExpr expr = new InfixExpr("2+3*4+5"); + Assert.assertEquals(19.0, expr.evaluate(), 0.001f); + } + { + InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); + Assert.assertEquals(100.0, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("3*20/2"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("20/2*3"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("10-30+50"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + } + +} diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/algorithm/LRUPageFrameTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LRUPageFrameTest.java similarity index 95% rename from group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/algorithm/LRUPageFrameTest.java rename to group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LRUPageFrameTest.java index 66bfd42119..828eab0881 100644 --- a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/algorithm/LRUPageFrameTest.java +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LRUPageFrameTest.java @@ -1,5 +1,6 @@ -package me.lzb.algorithm; +package me.lzb.basic; +import me.lzb.basic.LRUPageFrame; import org.junit.Assert; import org.junit.Test; diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/LinkedListTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LinkedListTest.java similarity index 98% rename from group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/LinkedListTest.java rename to group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LinkedListTest.java index 1914195aa5..6f02328060 100644 --- a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/LinkedListTest.java +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LinkedListTest.java @@ -1,7 +1,7 @@ -package me.lzb.datastructure; +package me.lzb.basic; -import me.lzb.datastructure.Iterator; -import me.lzb.datastructure.LinkedList; +import me.lzb.basic.Iterator; +import me.lzb.basic.LinkedList; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/StackUtilTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/StackUtilTest.java new file mode 100644 index 0000000000..48589f57d3 --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/StackUtilTest.java @@ -0,0 +1,78 @@ +package me.lzb.basic; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.Stack; + +public class StackUtilTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAddToBottom() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + + StackUtil.addToBottom(s, 0); + + Assert.assertEquals("[0, 1, 2, 3]", s.toString()); + + } + @Test + public void testReverse() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString()); + StackUtil.reverse(s); + Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString()); + } + + @Test + public void testRemove() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + StackUtil.remove(s, 2); + Assert.assertEquals("[1, 3]", s.toString()); + } + + @Test + public void testGetTop() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + { + Object[] values = StackUtil.getTop(s, 3); + Assert.assertEquals(5, values[0]); + Assert.assertEquals(4, values[1]); + Assert.assertEquals(3, values[2]); + } + Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString()); + } + + @Test + public void testIsValidPairs() { + Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])")); + Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})")); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/AttributeInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..fd000bdcb3 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/AttributeInfo.java @@ -0,0 +1,22 @@ +package me.lzb.jvm.attr; + +/** + * Created by LZB on 2017/4/15. + */ +public abstract class AttributeInfo { + + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + + int attrNameIndex; + int attrLen; + + public AttributeInfo(int attrNameIndex, int attrLen) { + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/CodeAttr.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..2addebeb39 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/CodeAttr.java @@ -0,0 +1,52 @@ +package me.lzb.jvm.attr; + +/** + * Created by LZB on 2017/4/15. + */ +public class CodeAttr extends AttributeInfo { + private int maxStack; + private int maxLocals; + private int codeLen; + private String code; + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen, String code /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + //this.cmds = cmds; + } + + + public String getCode() { + return code; + } + + public LineNumberTable getLineNumTable() { + return lineNumTable; + } + + public void setLineNumTable(LineNumberTable lineNumTable) { + this.lineNumTable = lineNumTable; + } + + public LocalVariableTable getLocalVarTable() { + return localVarTable; + } + + public void setLocalVarTable(LocalVariableTable localVarTable) { + this.localVarTable = localVarTable; + } + + public StackMapTable getStackMapTable() { + return stackMapTable; + } + + public void setStackMapTable(StackMapTable stackMapTable) { + this.stackMapTable = stackMapTable; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberItem.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberItem.java new file mode 100644 index 0000000000..e621cf925a --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberItem.java @@ -0,0 +1,31 @@ +package me.lzb.jvm.attr; + +/** + * Created by LZB on 2017/4/16. + */ +public class LineNumberItem { + int startPC; + int lineNum; + + + public LineNumberItem(int startPC, int lineNum) { + this.startPC = startPC; + this.lineNum = 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; +// } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberTable.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..5bf7b4759b --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberTable.java @@ -0,0 +1,23 @@ +package me.lzb.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by LZB on 2017/4/15. + */ +public class LineNumberTable extends AttributeInfo { + List items = new ArrayList<>(); + + + public void addLineNumberItem(LineNumberItem item) { + this.items.add(item); + } + + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + + } + + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableItem.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..decef772a3 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableItem.java @@ -0,0 +1,62 @@ +package me.lzb.jvm.attr; + +/** + * Created by LZB on 2017/4/15. + */ +public class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + + + public LocalVariableItem(int startPC, int length, int nameIndex, int descIndex, int index){ + this.startPC = startPC; + this.length = length; + this.nameIndex = nameIndex; + this.descIndex = descIndex; + this.index = index; + } + + + public int getStartPC() { + return startPC; + } + + public void setStartPC(int startPC) { + this.startPC = startPC; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getDescIndex() { + return descIndex; + } + + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableTable.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..9dca129d71 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableTable.java @@ -0,0 +1,20 @@ +package me.lzb.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by LZB on 2017/4/15. + */ +public class LocalVariableTable extends AttributeInfo { + List items = new ArrayList<>(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/StackMapTable.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..0b8947bdf8 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/StackMapTable.java @@ -0,0 +1,15 @@ +package me.lzb.jvm.attr; + +/** + * Created by LZB on 2017/4/15. + */ +public class StackMapTable extends AttributeInfo { + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen, String code) { + super(attrNameIndex, attrLen); + this.originalCode = code; + } + + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/AccessFlag.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..224714a010 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/AccessFlag.java @@ -0,0 +1,29 @@ +package me.lzb.jvm.clz; + +/** + * Created by LZB on 2017/4/14. + */ +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassFile.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..c5de9be5ce --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassFile.java @@ -0,0 +1,131 @@ +package me.lzb.jvm.clz; + +import me.lzb.jvm.constant.ConstantPool; +import me.lzb.jvm.field.Field; +import me.lzb.jvm.method.Method; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by LZB on 2017/4/14. + */ +public class ClassFile { + + private String magicNumber; + + private int minorVersion; + + private int majorVersion; + + private AccessFlag accessFlag; + + private ClassIndex clzIndex; + + + private ConstantPool constantPool; + + private List fields = new ArrayList<>(); + + private List methods = new ArrayList<>(); + + + public String getMagicNumber() { + return magicNumber; + } + + public void setMagicNumber(String magicNumber) { + this.magicNumber = magicNumber; + } + + public int getMinorVersion() { + return minorVersion; + } + + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + + public int getMajorVersion() { + return majorVersion; + } + + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + + + public AccessFlag getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + public ConstantPool getConstantPool() { + return constantPool; + } + + public void setConstantPool(ConstantPool constantPool) { + this.constantPool = constantPool; + } + + + + public List getFields() { + return fields; + } + + public void setFields(List fields) { + this.fields = fields; + } + + public List getMethods() { + return methods; + } + + public void setMethods(List methods) { + this.methods = methods; + } + + + + + + public ClassIndex getClzIndex() { + return clzIndex; + } + + public void setClzIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } +// System.out.println("Class Name:"+ getClassName()); +// +// System.out.println("Super Class Name:"+ getSuperClassName()); + + } + + + + + public int getConstantPoolCount() { + return constantPool.getSize(); + } + + public void addField(Field f){ + this.fields.add(f); + } + + public void addMethod(Method m){ + this.methods.add(m); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassIndex.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..8916290057 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassIndex.java @@ -0,0 +1,25 @@ +package me.lzb.jvm.clz; + +/** + * Created by LZB on 2017/4/14. + */ +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + + public int getSuperClassIndex() { + return superClassIndex; + } + + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ClassInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..200e59834a --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ClassInfo.java @@ -0,0 +1,33 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/14. + */ +public class ClassInfo extends ConstantInfo{ + private int type = ConstantInfo.Class_info; + private int utf8Index; + + public ClassInfo(ConstantPool pool) { + super(pool); + } + + @Override + public int getType() { + return type; + } + + public int getUtf8Index() { + return utf8Index; + } + + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..3bbabf2180 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantInfo.java @@ -0,0 +1,44 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/14. + */ +public abstract class ConstantInfo { + + public static final String MAGIC_NUMBER = "cafebabe"; + + public static final int Class_info = 7; + + public static final int Fieldref_info = 9; + + public static final int Methodref_info = 10; + + public static final int String_info = 8; + + public static final int NameAndType_info = 12; + + public static final int Utf8_info = 1; + + + + protected ConstantPool constantPool; + + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + + + public abstract int getType(); +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantPool.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..d78f0a71f4 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantPool.java @@ -0,0 +1,32 @@ +package me.lzb.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by LZB on 2017/4/14. + */ +public class ConstantPool { + + private List constantInfoList = new ArrayList<>(); + + + + public void addConstantInfo(ConstantInfo constantInfo){ + constantInfoList.add(constantInfo); + } + + + public int getSize(){ + return constantInfoList.size() > 1 ? constantInfoList.size() - 1 : 0; + } + + public ConstantInfo getConstantInfo(int index){ + return constantInfoList.get(index); + } + + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfoList.get(index)).getValue(); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/FieldRefInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..0ebab33b39 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/FieldRefInfo.java @@ -0,0 +1,35 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/15. + */ +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.Fieldref_info; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + @Override + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/MethodRefInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..263c185af5 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/MethodRefInfo.java @@ -0,0 +1,36 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/15. + */ +public class MethodRefInfo extends ConstantInfo { + private int type = ConstantInfo.Methodref_info; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + @Override + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NameAndTypeInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..bdf158ec37 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,36 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/15. + */ +public class NameAndTypeInfo extends ConstantInfo { + private int type = ConstantInfo.NameAndType_info; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + @Override + public int getType() { + return type; + } + + public int getIndex1() { + return index1; + } + + public void setIndex1(int index1) { + this.index1 = index1; + } + + public int getIndex2() { + return index2; + } + + public void setIndex2(int index2) { + this.index2 = index2; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NullConstantInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..7f9debba3b --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NullConstantInfo.java @@ -0,0 +1,12 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/14. + */ +public class NullConstantInfo extends ConstantInfo{ + + @Override + public int getType() { + return -1; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/StringInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..8ba36d8cfc --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/15. + */ +public class StringInfo extends ConstantInfo { + private int type = ConstantInfo.String_info; + + private int index; + + public StringInfo(ConstantPool pool) { + super(pool); + } + @Override + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/UTF8Info.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..d3f35c2fd7 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/UTF8Info.java @@ -0,0 +1,38 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/15. + */ +public class UTF8Info extends ConstantInfo { + private int type = ConstantInfo.Class_info; + + private String value; + + private int length; + + public UTF8Info(ConstantPool pool) { + super(pool); + } + + + @Override + public int getType() { + return type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/field/Field.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/field/Field.java new file mode 100644 index 0000000000..f388fd01bf --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/field/Field.java @@ -0,0 +1,30 @@ +package me.lzb.jvm.field; + +import me.lzb.jvm.constant.ConstantPool; + +/** + * Created by LZB on 2017/4/15. + */ +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private ConstantPool pool; + + public Field(int accessFlag, int nameIndex, int descriptorIndex ,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + @Override + public String toString() { + String key = pool.getUTF8String(nameIndex); + String value = pool.getUTF8String(descriptorIndex); + return key + ":" + value; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileLoader.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..593694066d --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileLoader.java @@ -0,0 +1,56 @@ +package me.lzb.jvm.loader; + + +import me.lzb.common.utils.FileUtils; +import me.lzb.jvm.clz.ClassFile; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList<>(); + + public byte[] readBinaryCode(String className) throws IOException { +// String fileName = className.replaceAll(".*\\.", "") + ".class"; +// String pkg = className.replaceAll("\\.[^\\.]+$", ""); +// String packagePath = pkg.replaceAll("\\.", "\\\\"); + + className = className.replace('.', File.separatorChar) + ".class"; + for (String s : clzPaths) { + byte[] data = FileUtils.readByteCodes(s + className); + if (data != null) { + return data; + } + } + + throw new IOException(className + "is not exist"); + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + public String getClassPath() { + StringBuilder buffer = new StringBuilder(); + for (Iterator iterator = clzPaths.iterator(); iterator.hasNext(); ) { + buffer.append(iterator.next() + (iterator.hasNext() ? ";" : "")); + } + return buffer.toString(); + } + + + public ClassFile loadClass(String className) throws IOException { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(codes); + return parser.parse(); + } + + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileParser.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..bfd3cbc2c0 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileParser.java @@ -0,0 +1,331 @@ +package me.lzb.jvm.loader; + +import me.lzb.common.utils.ByteUtils; +import me.lzb.common.utils.StringUtils; +import me.lzb.jvm.attr.*; +import me.lzb.jvm.clz.AccessFlag; +import me.lzb.jvm.clz.ClassFile; +import me.lzb.jvm.clz.ClassIndex; +import me.lzb.jvm.constant.*; +import me.lzb.jvm.field.Field; +import me.lzb.jvm.method.Method; + +import java.io.UnsupportedEncodingException; + +/** + * 处理字class文件字节流 + * Created by LZB on 2017/4/14. + */ +public class ClassFileParser { + + + private final byte[] data; + + private int index; + + public ClassFileParser(byte[] data) { + this.data = data; + } + + + public ClassFile parse() { + ClassFile classFile = new ClassFile(); + parserMagicNumber(classFile); + + if (!StringUtils.equals(classFile.getMagicNumber(), ConstantInfo.MAGIC_NUMBER)) { + throw new RuntimeException("It is not a java class file."); + } + + parserVersion(classFile); + + parserConstantPool(classFile); + + parserAccessFlag(classFile); + + parserClassIndex(classFile); + + parserInterface(classFile); + + parserField(classFile); + + parserMethod(classFile); + + return classFile; + } + + + private byte[] nextBytes(int nextLength) { + byte[] target = new byte[nextLength]; + System.arraycopy(data, index, target, 0, nextLength); + index = index + nextLength; + return target; + } + + private int nextBytesToInt(int nextLength) { + return ByteUtils.byteToInt(nextBytes(nextLength)); + } + + private String nextBytesToString(int nextLength) { + return ByteUtils.byteToHexString(nextBytes(nextLength)); + } + + + private void parserMagicNumber(ClassFile classFile) { + this.index = 0; + classFile.setMagicNumber(nextBytesToString(4)); + } + + private void parserVersion(ClassFile classFile) { + classFile.setMinorVersion(nextBytesToInt(2)); + classFile.setMajorVersion(nextBytesToInt(2)); + } + + private void parserConstantPool(ClassFile classFile) { + int count = nextBytesToInt(2); + + ConstantPool pool = new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); + + for (int i = 1; i < count; i++) { + + int tag = nextBytesToInt(1); + + if (tag == ConstantInfo.Class_info) { + ClassInfo classInfo = new ClassInfo(pool); + classInfo.setUtf8Index(nextBytesToInt(2)); + + pool.addConstantInfo(classInfo); + continue; + } + + if (tag == ConstantInfo.Fieldref_info) { + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + fieldRefInfo.setClassInfoIndex(nextBytesToInt(2)); + fieldRefInfo.setNameAndTypeIndex(nextBytesToInt(2)); + + pool.addConstantInfo(fieldRefInfo); + continue; + } + + if (tag == ConstantInfo.Methodref_info) { + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + methodRefInfo.setClassInfoIndex(nextBytesToInt(2)); + methodRefInfo.setNameAndTypeIndex(nextBytesToInt(2)); + + pool.addConstantInfo(methodRefInfo); + continue; + } + + if (tag == ConstantInfo.NameAndType_info) { + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + nameAndTypeInfo.setIndex1(nextBytesToInt(2)); + nameAndTypeInfo.setIndex2(nextBytesToInt(2)); + + pool.addConstantInfo(nameAndTypeInfo); + continue; + } + + if (tag == ConstantInfo.String_info) { + StringInfo stringInfo = new StringInfo(pool); + stringInfo.setIndex(nextBytesToInt(2)); + + pool.addConstantInfo(stringInfo); + continue; + } + + if (tag == ConstantInfo.Utf8_info) { + UTF8Info utf8Info = new UTF8Info(pool); + int len = nextBytesToInt(2); + byte[] data = nextBytes(len); + String value = null; + try { + value = new String(data, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + utf8Info.setLength(len); + utf8Info.setValue(value); + + pool.addConstantInfo(utf8Info); + continue; + } + + + throw new RuntimeException("the constant pool tag " + tag + " has not been implemented yet." + i); + } + + + classFile.setConstantPool(pool); + } + + + private void parserAccessFlag(ClassFile classFile) { + AccessFlag flag = new AccessFlag(nextBytesToInt(2)); + classFile.setAccessFlag(flag); + } + + + private void parserClassIndex(ClassFile classFile) { + ClassIndex clzIndex = new ClassIndex(); + + int thisClassIndex = nextBytesToInt(2); + int superClassIndex = nextBytesToInt(2); + clzIndex.setThisClassIndex(thisClassIndex); + clzIndex.setSuperClassIndex(superClassIndex); + + classFile.setClzIndex(clzIndex); + } + + private void parserInterface(ClassFile classFile) { + int count = nextBytesToInt(2); + //TODO 实现interface + } + + + private void parserField(ClassFile classFile) { + int count = nextBytesToInt(2); + for (int i = 1; i <= count; i++) { + int accessFlags = nextBytesToInt(2); + int nameIndex = nextBytesToInt(2); + int descriptorIndex = nextBytesToInt(2); + int attributesCount = nextBytesToInt(2); + + if (attributesCount > 0) { + throw new RuntimeException("Field Attribute has not been implement"); + } + + Field field = new Field(accessFlags, nameIndex, descriptorIndex, classFile.getConstantPool()); + classFile.addField(field); + } + } + + private void parserMethod(ClassFile classFile) { + int count = nextBytesToInt(2); + for (int i = 1; i <= count; i++) { + int accessFlags = nextBytesToInt(2); + int nameIndex = nextBytesToInt(2); + int descriptorIndex = nextBytesToInt(2); + int attributesCount = nextBytesToInt(2); + + + Method method = new Method(accessFlags, nameIndex, descriptorIndex); + + + for (int j = 1; j <= attributesCount; j++) { + + int attributeNameIndex = nextBytesToInt(2); + + String attributeName = classFile.getConstantPool().getUTF8String(attributeNameIndex); + + if (StringUtils.equalsIgnoreCase(attributeName, AttributeInfo.CODE)) { + parserCodeAttr(attributeNameIndex, method, classFile); + continue; + } + + + throw new RuntimeException("only CODE attribute is implemented."); + } + + classFile.addMethod(method); + + } + } + + + private void parserCodeAttr(int attributeNameIndex, Method method, ClassFile classFile) { + int attributeLength = nextBytesToInt(4); + int maxStack = nextBytesToInt(2); + int maxLocals = nextBytesToInt(2); + int codeLength = nextBytesToInt(4); + + String code = nextBytesToString(codeLength); + CodeAttr codeAttr = new CodeAttr(attributeNameIndex, attributeLength, maxStack, maxLocals, codeLength, code); + + int exceptionTableLength = nextBytesToInt(2); + if (exceptionTableLength > 0) { + String exceptionTable = nextBytesToString(exceptionTableLength); + //TODO 异常 + } + + + int subAttrCount = nextBytesToInt(2); + for (int k = 1; k <= subAttrCount; k++) { + int subAttrIndex = nextBytesToInt(2); + + String subAttrName = classFile.getConstantPool().getUTF8String(subAttrIndex); + + if (StringUtils.equalsIgnoreCase(subAttrName, AttributeInfo.LINE_NUM_TABLE)) { + + parserLineNumberTable(codeAttr, subAttrIndex); + continue; + } + + if (StringUtils.equalsIgnoreCase(subAttrName, AttributeInfo.LOCAL_VAR_TABLE)) { + parserLocalVariableTable(codeAttr, subAttrIndex); + continue; + } + + if (StringUtils.equalsIgnoreCase(subAttrName, AttributeInfo.STACK_MAP_TABLE)) { + parserStackMapTable(codeAttr, subAttrIndex); + continue; + } + + + throw new RuntimeException("Need code to process" + subAttrName); + } + + + method.setCodeAttr(codeAttr); + } + + + private void parserLineNumberTable(CodeAttr codeAttr, int attributeNameIndex) { +// int attributeNameIndex = nextBytesToInt(2); + int attributeLength = nextBytesToInt(4); + + int lineNumberTableLength = nextBytesToInt(2); + + LineNumberTable table = new LineNumberTable(attributeNameIndex, attributeLength); + + for (int l = 1; l <= lineNumberTableLength; l++) { + int startPc = nextBytesToInt(2); + int lineNumber = nextBytesToInt(2); + LineNumberItem item = new LineNumberItem(startPc, lineNumber); + table.addLineNumberItem(item); + } + + codeAttr.setLineNumTable(table); + } + + + private void parserLocalVariableTable(CodeAttr codeAttr, int attributeNameIndex) { +// int attributeNameIndex = nextBytesToInt(2); + int attributeLength = nextBytesToInt(4); + + int localVariableTableLength = nextBytesToInt(2); + + LocalVariableTable table = new LocalVariableTable(attributeNameIndex, attributeLength); + + for (int l = 1; l <= localVariableTableLength; l++) { + int startPc = nextBytesToInt(2); + int lineNumber = nextBytesToInt(2); + int nameIndex = nextBytesToInt(2); + int descriptorIndex = nextBytesToInt(2); + int index = nextBytesToInt(2); + LocalVariableItem item = new LocalVariableItem(startPc, lineNumber, nameIndex, descriptorIndex, index); + table.addLocalVariableItem(item); + } + + codeAttr.setLocalVarTable(table); + } + + private void parserStackMapTable(CodeAttr codeAttr, int attributeNameIndex) { +// int attributeNameIndex = nextBytesToInt(2); + int attributeLength = nextBytesToInt(4); + String code = nextBytesToString(attributeLength); + StackMapTable table = new StackMapTable(attributeNameIndex, attributeLength, code); + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + codeAttr.setStackMapTable(table); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/method/Method.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/method/Method.java new file mode 100644 index 0000000000..9c3e9ad984 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/method/Method.java @@ -0,0 +1,65 @@ +package me.lzb.jvm.method; + +import me.lzb.jvm.attr.CodeAttr; + +/** + * Created by LZB on 2017/4/15. + */ +public class Method { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + +// private ClassFile clzFile; + + + public Method(/*ClassFile clzFile,*/ int accessFlag, int nameIndex, int descriptorIndex) { +// this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + public int getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(int accessFlag) { + this.accessFlag = accessFlag; + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public void setDescriptorIndex(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr codeAttr) { + this.codeAttr = codeAttr; + } + +// public ClassFile getClzFile() { +// return clzFile; +// } +// +// public void setClzFile(ClassFile clzFile) { +// this.clzFile = clzFile; +// } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/loader/ClassFileLoader.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/loader/ClassFileLoader.java deleted file mode 100644 index 86f017cebf..0000000000 --- a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/loader/ClassFileLoader.java +++ /dev/null @@ -1,57 +0,0 @@ -package me.lzb.loader; - -import me.lzb.utils.FileUtils; -import me.lzb.utils.StringUtils; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - - - -public class ClassFileLoader { - - private List clzPaths = new ArrayList<>(); - - public byte[] readBinaryCode(String className) throws IOException { - String fileName = className.replaceAll(".*\\.", "") + ".class"; - String pkg = className.replaceAll("\\.[^\\.]+$", ""); - String packagePath = pkg.replaceAll("\\.", "\\\\"); - - - String path = ""; - for (String s : clzPaths) { - if (FileUtils.isFileExist(s + packagePath, fileName)){ - path = s; - break; - } - } - - if(StringUtils.isBlank(path)){ - throw new IOException("class file not found"); - } - - return FileUtils.readByteCodes(path + packagePath + "\\" + fileName); - - } - - - public void addClassPath(String path) { - clzPaths.add(path); - } - - - - public String getClassPath(){ - StringBuilder buffer = new StringBuilder(); - for (Iterator iterator = clzPaths.iterator(); iterator.hasNext();) { - buffer.append(iterator.next() + (iterator.hasNext() ? ";" : "")); - } - return buffer.toString(); - } - - - - -} diff --git a/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/ClassFileloaderTest.java b/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/ClassFileloaderTest.java new file mode 100644 index 0000000000..f41b313c97 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/ClassFileloaderTest.java @@ -0,0 +1,269 @@ +package me.lzb.jvm; + +import me.lzb.common.utils.ByteUtils; +import me.lzb.jvm.clz.ClassFile; +import me.lzb.jvm.clz.ClassIndex; +import me.lzb.jvm.constant.*; +import me.lzb.jvm.field.Field; +import me.lzb.jvm.loader.ClassFileLoader; +import me.lzb.jvm.method.Method; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.List; + + +public class ClassFileloaderTest { + + + static String path1 = EmployeeV1.class.getResource("/").getPath(); +// static String path1 = "D:\\code\\learning\\coding2017\\group24\\1148285693\\learning2017\\mini-jvm\\target\\test-classes\\"; + static String path2 = "C:\\temp"; + + static String className = "me.lzb.jvm.EmployeeV1"; + + private static final String FULL_QUALIFIED_CLASS_NAME = "me/lzb/jvm/EmployeeV1"; +// private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + + @Test + public void testPath() { + + String s = EmployeeV1.class.getResource("/").getPath(); + String s2 = EmployeeV1.class.getResource("").getPath(); + System.out.println(s); + System.out.println(s2); + + } + + + @Test + public void testClassPath() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1 + ";" + path2, clzPath); + + } + + @Test + public void testClassFileLength() throws Exception { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + + byte[] byteCodes = loader.readBinaryCode(className); + + Assert.assertEquals(1030, byteCodes.length); + + } + + + @Test + public void testMagicNumber() throws Exception { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3]}; + + String acctualValue = ByteUtils.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + static ClassFile clzFile = null; + + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + try { + clzFile = loader.loadClass(className); + } catch (IOException e) { + e.printStackTrace(); + } + clzFile.print(); + } + + + @Test + public void testVersion() { + + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool() { + + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(7); + Assert.assertEquals(44, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(44); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(11); + Assert.assertEquals(48, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(48); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(12); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(13); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(14); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(15); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(16); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(17); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(18); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo) pool.getConstantInfo(1); + Assert.assertEquals(11, methodRef.getClassInfoIndex()); + Assert.assertEquals(36, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(36); + Assert.assertEquals(16, nameAndType.getIndex1()); + Assert.assertEquals(28, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo) pool.getConstantInfo(10); + Assert.assertEquals(7, methodRef.getClassInfoIndex()); + Assert.assertEquals(47, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(35); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + + @Test + public void testClassIndex() { + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo) clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo) clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + /** + * 下面是第三次JVM课应实现的测试用例 + */ + @Test + public void testReadFields() { + + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + + @Test + public void testMethods() { + + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool, m, + "", + "(Ljava/lang/String;I)V", + "2ab700012a2bb500022a1cb50003b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool, m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb50002b1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool, m, + "setAge", + "(I)V", + "2a1bb50003b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool, m, + "sayHello", + "()V", + "b200041205b60006b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool, m, + "main", + "([Ljava/lang/String;)V", + "bb0007591208101db700094c2bb6000ab1"); + } + } + + private void assertMethodEquals(ConstantPool pool, Method m, String expectedName, String expectedDesc, String expectedCode) { + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/EmployeeV1.java b/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/EmployeeV1.java similarity index 95% rename from group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/EmployeeV1.java rename to group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/EmployeeV1.java index ab035ac403..3fa9b0fc85 100644 --- a/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/EmployeeV1.java +++ b/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/EmployeeV1.java @@ -1,4 +1,4 @@ -package me.lzb.loader; +package me.lzb.jvm; public class EmployeeV1 { diff --git a/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/ClassFileloaderTest.java b/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/ClassFileloaderTest.java deleted file mode 100644 index b544e7ddc4..0000000000 --- a/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/ClassFileloaderTest.java +++ /dev/null @@ -1,103 +0,0 @@ -package me.lzb.loader; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - - - - - -public class ClassFileloaderTest { - - - static String path1 = EmployeeV1.class.getResource("/").getPath(); - static String path2 = "C:\\temp"; - - - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - - - @Test - public void testPath(){ - - String s = EmployeeV1.class.getResource("/").getPath(); - String s2 = EmployeeV1.class.getResource("").getPath(); - System.out.println(s); - System.out.println(s2); - - } - - - - @Test - public void testClassPath(){ - - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - loader.addClassPath(path2); - - String clzPath = loader.getClassPath(); - - Assert.assertEquals(path1+";"+path2,clzPath); - - } - - @Test - public void testClassFileLength() throws Exception{ - - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - - String className = "me.lzb.loader.EmployeeV1"; - - byte[] byteCodes = loader.readBinaryCode(className); - - // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 - Assert.assertEquals(1036, byteCodes.length); - - } - - - @Test - public void testMagicNumber() throws Exception{ - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - String className = "me.lzb.loader.EmployeeV1"; - byte[] byteCodes = loader.readBinaryCode(className); - byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; - - String acctualValue = this.byteToHexString(codes); - - Assert.assertEquals("cafebabe", acctualValue); - } - - - - - - - private String byteToHexString(byte[] codes ){ - StringBuffer buffer = new StringBuffer(); - for(int i=0;i[] edgeList; + + /** + * 边 + */ + private class Edge { + /** + * 边的id + */ + int id; + + /** + * 是否被正向搜索 + */ + boolean isSearched; + + /** + * 顶点v + */ + int v; + + /** + * 顶点b + */ + int w; + + /** + * 保存回滚操作中,被回滚的的路径方向,以及,前提路径 + * 因为在不同级别的回滚中,可能会有多条临时路径,所以用list存放 + * 顶点->顶点:路径id->路径id->路径id + * 1->2:0->1->2 + */ + ArrayList to = new ArrayList<>(); + + /** + * 构造函数 + * @param v 顶点v + * @param w 顶点w + */ + public Edge(int v, int w) { + this.v = v; + this.w = w; + isSearched = false; + id = edgeCount; + } + + + /** + * 在当前前提路径下,是否有 + * @param v0 出发顶点 + * @param P 前提路径 + * @return true false + */ + public boolean isFrom(int v0, String P) { + return isTheSameTo(v0, getAnotherV(v0), P); + } + + /** + * 临时路径是否相同 + * @param v0 出发顶点 + * @param v1 到达顶点 + * @param p 前提路径 + * @return true false + */ + public boolean isTheSameTo(int v0, int v1, String p) { + if (to.size() == 0) { + return false; + } + String ss = v0 + PATH_SEPARATOR + v1 + ":" + p; + for (String s : to) { + if (ss.equals(s)) { + return true; + } + } + return false; + } + + /** + * 删除临时路径 + * @param v0 出发顶点 + * @param v1 到达顶点 + * @param p 前提路径 + */ + public void removeTo(int v0, int v1, String p) { + if (to.size() == 0) { + return; + } + String ss = v0 + PATH_SEPARATOR + v1 + ":" + p; + for (Iterator iterator = to.iterator(); iterator.hasNext(); ) { + String s = iterator.next(); + if (ss.equals(s)) { + iterator.remove(); + return; + } + } + } + + /** + * 增加临时路径 + * @param v0 出发顶点 + * @param v1 到达顶点 + * @param p 前提路径 + */ + public void addTo(int v0, int v1, String p) { + String ss = v0 + PATH_SEPARATOR + v1 + ":" + p; + for (String s : to) { + if (ss.equals(s)) { + return; + } + } + to.add(ss); + + } + + /** + * 获取边的另外一条顶点 + * @param vertex + * @return + */ + public int getAnotherV(int vertex) { + if (vertex == v) { + return w; + } else { + return v; + } + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Edge c = (Edge) obj; + return this.id == c.id; + } + + @Override + public int hashCode() { + return id; + } + } + + /** + * 构造函数 + * @param vertexNum 顶点总数 + * @param edgeCount 边的总数 + */ + public Graph(int vertexNum, int edgeCount) { + this.vertexCount = vertexNum; + this.edgeCount = 0; + edgeList = new LinkedList[edgeCount]; + for (int i = 0; i < edgeCount; i++) { + edgeList[i] = new LinkedList<>(); + } + } + + public void addEdge(int v1, int v2) { + Edge c = new Edge(v2, v1); + edgeList[v1].add(c); + edgeList[v2].add(c); + edgeCount++; + } + + + public void addEdge(int[][] edgeArray) { + for (int i = 0; i < edgeArray.length; i++) { + addEdge(edgeArray[i][0], edgeArray[i][1]); + } + } + + public String toString() { + StringBuilder s = new StringBuilder(); + s.append(vertexCount + " vertices, " + edgeCount + " edges " + NEWLINE); + for (int v = 0; v < vertexCount; v++) { + s.append(v + ": "); + for (Edge w : edgeList[v]) { + s.append(w.getAnotherV(v) + " "); + } + s.append(NEWLINE); + } + return s.toString(); + } + + + /** + * 更新出现过路径的最长边数 + * @param a + */ + private void updateMax(int a) { + if (a > maxEdge) { + maxEdge = a; + } + } + + + public boolean isEuler() { + int start = 0; + Stack stack = new Stack<>(); + stack.push(start); + + //TODO 退出递归的条件 +// try { + search(start, start, stack, new Stack<>()); +// }catch (EmptyStackException e){ + +// } + + System.out.println("最长边数:" + maxEdge); + return maxEdge == edgeCount; + } + + + + + /** + * 正向搜索 + * 传进去一个节点,顺着一条没有搜索过的边找到下一个节点。当搜索到死路时,回滚 + * @param v 当前提点 + * @param stack 当前路径的节点顺序 + * @param sp 当前路径的路径顺序 + */ + public void search(int start, int v, Stack stack, Stack sp) { + + LinkedList list = edgeList[v]; + + boolean anotherWay = false; + for (Edge w : list) { + if (!w.isSearched && !w.isTheSameTo(v, w.getAnotherV(v), getPath(sp))) { + anotherWay = true; + w.isSearched = true; + stack.push(w.getAnotherV(v)); + updateMax(sp.size()); + sp.push(w); + search(start, w.getAnotherV(v), stack, sp); + } + } + + if (!anotherWay) { + System.out.println("最长:==============================="); + rollback(start, stack, sp); + } + + } + + + + /** + * 回滚,回滚当上一个节点,如果当前节点有可以使用的边,调用搜索,如果没有,递归继续回滚 + * 如果需要递归回滚,回滚到第二级之前,清空所有,当前路径下,从该点出发的方向 + * 被回滚的路径,需要保存路径方向,以及提前路径 + * @param stack 当前路径的节点顺序 + * @param sp 当前路径的路径顺序 + */ + public void rollback(int start, Stack stack, Stack sp) { + + String ss = getPath(sp); + String output = "顶点:" + stack.toString() + + NEWLINE + "路径:" + ss + + NEWLINE; + System.out.println(output); + +// if(stack.size() == 1){ +// return; +// } + + + Edge e = sp.pop(); //需要回滚的路径 + String pp = getPath(sp); //前提路径 + + int vz = stack.pop(); + int vy = stack.peek(); + + boolean rollbakc2 = true; + + LinkedList l = edgeList[vy]; + + //判断当前节点是否存在空闲路径,是否要回滚两级 + //空闲路径:没有被正向搜索,也没有被缓存当前前提路径下,从改节点出发的方向 + for (Edge w : l) { + if (!w.isSearched && !w.isTheSameTo(vy, w.getAnotherV(vy), pp)) { + rollbakc2 = false; + break; + } + } + + + //回滚当前路径,回滚一级 + int r = vy; + for (Edge w : l) { + if (w.equals(e)) { + w.addTo(vy, vz, pp); + w.isSearched = false; + break; + } + } + + if (rollbakc2) { + //回滚两级, 清空所有,当前路径下,从该点出发的方向 + + for (Edge w : l) { + if (!w.isSearched && w.isFrom(vy, pp)) { + w.removeTo(vy, w.getAnotherV(vy), pp); + } + } + rollback(start, stack, sp); + } + + search(start, r, stack, sp); + + } + + public String getPath(Stack stack) { + String s = ""; + for (Edge x : stack) { + s = s + x.id + PATH_SEPARATOR; + } + s = s.replaceAll(PATH_SEPARATOR + "$", ""); + return s; + } + + + public static void main(String[] args) { + int[][] aa = new int[][]{{0, 1}, {0, 1}, {0, 3}, {1, 3}, {1, 2}, {1, 2}, {2, 3}}; + Graph g = new Graph(4, aa.length); + g.addEdge(aa); + System.out.println(g.toString()); + System.out.println(g.isEuler()); + } +} diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest1.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest1.java new file mode 100644 index 0000000000..4b8b3d4ce8 --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest1.java @@ -0,0 +1,27 @@ +package me.lzb.other.lock; + +/** + * Created by LZB on 2017/3/30. + */ +public class ReentrantTest1 implements Runnable{ + + public synchronized void get(){ + System.out.println(Thread.currentThread().getId()); + set(); + } + + public synchronized void set(){ + System.out.println(Thread.currentThread().getId()); + } + + @Override + public void run() { + get(); + } + public static void main(String[] args) { + ReentrantTest1 ss=new ReentrantTest1(); + new Thread(ss).start(); + new Thread(ss).start(); + new Thread(ss).start(); + } +} \ No newline at end of file diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest2.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest2.java new file mode 100644 index 0000000000..c630ea9e33 --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest2.java @@ -0,0 +1,35 @@ +package me.lzb.other.lock; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by LZB on 2017/3/30. + */ +public class ReentrantTest2 implements Runnable { + ReentrantLock lock = new ReentrantLock(); + + public void get() { + lock.lock(); + System.out.println(Thread.currentThread().getId()); + set(); + lock.unlock(); + } + + public void set() { + lock.lock(); + System.out.println(Thread.currentThread().getId()); + lock.unlock(); + } + + @Override + public void run() { + get(); + } + + public static void main(String[] args) { + ReentrantTest2 ss = new ReentrantTest2(); + new Thread(ss).start(); + new Thread(ss).start(); + new Thread(ss).start(); + } +} \ No newline at end of file diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/MyInvocationHandler.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/MyInvocationHandler.java new file mode 100644 index 0000000000..d89298c786 --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/MyInvocationHandler.java @@ -0,0 +1,52 @@ +package me.lzb.other.proxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * Created by LZB on 2017/3/29. + */ +public class MyInvocationHandler implements InvocationHandler { + + // 目标对象 + private Object target; + + /** + * 构造方法 + * + * @param target 目标对象 + */ + public MyInvocationHandler(Object target) { + super(); + this.target = target; + } + + + /** + * 执行目标对象的方法 + */ + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + + // 在目标对象的方法执行之前简单的打印一下 + System.out.println("------------------before------------------"); + + // 执行目标对象的方法 + Object result = method.invoke(target, args); + + // 在目标对象的方法执行之后简单的打印一下 + System.out.println("-------------------after------------------"); + + return result; + } + + /** + * 获取目标对象的代理对象 + * + * @return 代理对象 + */ + public Object getProxy() { + return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), + target.getClass().getInterfaces(), this); + } +} diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserService.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserService.java new file mode 100644 index 0000000000..d57431acab --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserService.java @@ -0,0 +1,11 @@ +package me.lzb.other.proxy; + +/** + * Created by LZB on 2017/3/29. + */ +public interface UserService { + /** + * 目标方法 + */ + void add(); +} diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserServiceImpl.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserServiceImpl.java new file mode 100644 index 0000000000..614b60d9c9 --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserServiceImpl.java @@ -0,0 +1,11 @@ +package me.lzb.other.proxy; + +/** + * Created by LZB on 2017/3/29. + */ +public class UserServiceImpl implements UserService { + + public void add() { + System.out.println("--------------------add---------------"); + } +} \ No newline at end of file diff --git a/group24/1148285693/learning2017/other/src/test/java/me/lzb/other/proxy/ProxyTest.java b/group24/1148285693/learning2017/other/src/test/java/me/lzb/other/proxy/ProxyTest.java new file mode 100644 index 0000000000..0a01679ad3 --- /dev/null +++ b/group24/1148285693/learning2017/other/src/test/java/me/lzb/other/proxy/ProxyTest.java @@ -0,0 +1,25 @@ +package me.lzb.other.proxy; + +import org.junit.Test; + +/** + * Created by LZB on 2017/3/29. + */ +public class ProxyTest { + + @Test + public void testProxy() throws Throwable { + // 实例化目标对象 + UserService userService = new UserServiceImpl(); + + // 实例化InvocationHandler + MyInvocationHandler invocationHandler = new MyInvocationHandler(userService); + + // 根据目标对象生成代理对象 + UserService proxy = (UserService) invocationHandler.getProxy(); + + // 调用代理对象的方法 + proxy.add(); + + } +} diff --git a/group24/1148285693/learning2017/pom.xml b/group24/1148285693/learning2017/pom.xml index 9b8d948ff9..8dc41781ba 100644 --- a/group24/1148285693/learning2017/pom.xml +++ b/group24/1148285693/learning2017/pom.xml @@ -22,9 +22,10 @@ + common learning-basic mini-jvm - + other @@ -103,6 +104,11 @@ commons-codec 1.10 + + org.apache.commons + commons-collections4 + 4.1 +