From 570006c7206404adcdd7b6817c55337302ddfc78 Mon Sep 17 00:00:00 2001 From: liuyang Date: Tue, 21 Mar 2017 11:30:40 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/coding/basic/LinkedList.java | 463 +++++++++++++++++- .../src/com/coding/basic/LinkedListTest.java | 295 +++++++++++ 2 files changed, 744 insertions(+), 14 deletions(-) create mode 100644 group21/28394073/homework/src/com/coding/basic/LinkedListTest.java diff --git a/group21/28394073/homework/src/com/coding/basic/LinkedList.java b/group21/28394073/homework/src/com/coding/basic/LinkedList.java index e2c4e5e795..62f0f924c2 100644 --- a/group21/28394073/homework/src/com/coding/basic/LinkedList.java +++ b/group21/28394073/homework/src/com/coding/basic/LinkedList.java @@ -1,46 +1,481 @@ package com.coding.basic; +import java.util.ArrayList; + + + public class LinkedList implements List { - private Node head; + private Node head ; + + private static class Node{ + Object data; + Node next; + + } + /** + * @param head + */ + public LinkedList() { +// super();// Incorrect +// head = null; //Incorrect + head=new Node(); + } + + public LinkedList(int[] array){ + this.head = new Node(); + if(array.length==0){ + return; + } + if(array.length==1){ + this.head.data = array[0]; + this.head.next = null; + } + else{ + Node curNode = new Node(); + for(int i=0;i"; + curNode = curNode.next; + str = str + String.valueOf(curNode.data); + } + System.out.println(str); + return str; + } + + + //Add在整个linklist的尾部 public void add(Object o){ +// if(head==null){ //It is always "False" because of Constructor + if(head.data==null){ + head.data=o; + head.next=null; + }else{ + Node newNode = new Node(); + Node preNode = new Node(); + preNode = head; + while(preNode.next!=null){ + preNode = preNode.next; + } + preNode.next = newNode; + newNode.data = o; + newNode.next = null; + } + } - public void add(int index , Object o){ + + //把返回类型改成Boolean,觉得Boolean更好,且适合单元测试。 + public Boolean add(int index , Object o){ + if(index==0){ + this.addFirst(o); + return true; + } + if(index==this.size()){ + this.addLast(o); + return true; + } + if(index>this.size()){ + System.out.println("Error:index should not be larger than size of the linklist!!"); + return false; + } + else{ + Node newNode = new Node(); + newNode.data = o; + Node preNode = head; + Node postNode = preNode.next; + Boolean flag = true; + while(flag){ + if(--index==0){ + break; + } + preNode = postNode; + postNode = preNode.next; + } + preNode.next = newNode; + newNode.next = postNode; + return true; + } } + + public Object get(int index){ - return null; + if(index>=this.size()){ + return null; + }else{ + Boolean flag = true; + Node node = head; + while(index--!=0){ + node=node.next; + } + return node.data; + } + + } - public Object remove(int index){ - return null; + + + public Boolean remove(int index){ + if(index==0){ + this.removeFirst(); + return true; + } + if(index>=this.size()){ + return false; + }else{ + Node preNode = head; + Node postNode = preNode.next; + Boolean flag = true; + while(flag){ + if(--index==0){ + break; + } + preNode = postNode; + postNode = preNode.next; + } + preNode.next = postNode.next; + return true; + } } public int size(){ - return -1; + if(head.data==null){ + return 0; + } + else + { + int size = 1; + Node node = head; + while(node.next!=null){ + size++; + node = node.next; + } + return size; + } } public void addFirst(Object o){ + if(head.data == null){ + head.data = o; + head.next = null; + } + else{ + Node addItem = new Node(); + addItem.data = o; + addItem.next = head; + head = addItem; + } } public void addLast(Object o){ - + this.add(o); } - public Object removeFirst(){ - return null; + + public Boolean removeFirst(){ + if(head.data == null){ + return false; + } + if(head.next == null){ + head = null; + return true; + }else{ + head = head.next; + return true; + } } - public Object removeLast(){ - return null; + + public Boolean removeLast(){ + if(head.data == null){ + return false; + } + if(head.next == null){ + head = null; + return true; + }else{ + Node preNode = head; + Node postNode = head.next; + while(postNode.next!=null){ + preNode = postNode; + postNode = postNode.next; + } + preNode.next = null; + return true; + } } + public Iterator iterator(){ return null; } - private static class Node{ - Object data; - Node next; + + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if(head.data==null){ + System.out.println("This is an empty linklist!!"); + return; + } + if(this.size()==1){ + System.out.println("It is itself!!"); + return; + } + else{ + Node preNode = head; + Node curNode = head.next; + Node postNode = curNode.next; + head.next = null; + while(postNode!=null){ + curNode.next = preNode; + preNode = curNode; + curNode = postNode; + postNode = postNode.next;//如果while循环判断的是curNode!=null,那这里有问题,最后一轮循环postNode已经是null,所以postNode.next就会InvocationException + }//while end + curNode.next = preNode; + head = curNode; + }//else end + } + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int index = (int)this.size()/2; + Node curNode = new Node(); +// Node postNode = new Node(); + curNode = head; +// postNode = head.next; + while(index--!=0){ + curNode = curNode.next; +// postNode = postNode.next; + } + head = curNode; + head.next = curNode.next; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if(i>=this.size() || i+length>this.size()){ + System.out.println("Error!!"); + return; + } + if(head.next==null){ + if(i+length == 0){//remove(0,0)则不删 + return; + }else //remove(0,1) 删 + head.data = null; + return; + } + else{ + Node curNode = head; + Node postNode = head.next; + while(--i!=0 && i>0){ + curNode = postNode; + postNode = postNode.next; + }//while end - loop 1 + Node delNode = postNode; + Node delpostNode = postNode.next; + while(--length!=0 && length>0){ + delNode = delpostNode; + delpostNode = delNode.next; + }//while end - loop 2 + delNode.next = null; + curNode.next = delpostNode; + } + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + + //Why set this function as static? I change it to non-static. + public int[] getElements(LinkedList list){ + int sublistSize = list.size(); + int listSize = this.size(); + if(Integer.parseInt(list.get(sublistSize-1).toString())>=listSize){ + System.out.println("Out of boundary!"); + return null; + }//判断越界 + + int[] results = new int[sublistSize]; + for(int i=0;i(int)bPoint.data){ + bPoint = bPoint.next; + if(bPoint==null) + break; + } + if((int)aPoint.data==(int)bPoint.data){ + if(aPoint.equals(this.head)){ + this.head = aPoint.next; + }else{ + aPoint = aPoint.next; + aPreNode.next = aPoint; + bPoint = bPoint.next; + } + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + Node preNode = this.head; + Node curNode = preNode.next; + while(curNode!=null){ + if(Integer.parseInt(preNode.data.toString()) == Integer.parseInt(curNode.data.toString())){ + //思考,这里为什么不能用Integer.valueof(String s)? + curNode = curNode.next; + preNode.next = curNode; + + }else{ + preNode = curNode; + curNode = curNode.next; + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + if(min>max||min<0){ + return; + } + else{ + Node preNode = this.head; + Node curNode = preNode.next; + Node fixNode = new Node(); + while(Integer.parseInt(preNode.data.toString())=min){ + fixNode = preNode; + while(Integer.parseInt(preNode.data.toString())<=max&&Integer.parseInt(curNode.data.toString())<=max){ + preNode = curNode; + curNode = curNode.next; + } + if(Integer.parseInt(curNode.data.toString())>max){ + fixNode.next = curNode; + } + } + } + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + if(list.head==null){ + return this; + } + if(this.head==null){ + return list; + }else{ + LinkedList clist = new LinkedList(); + Node aPoint = this.head; + Node bPoint = list.head; + while(aPoint != null && bPoint != null){ + if(Integer.parseInt(aPoint.data.toString())Integer.parseInt(bPoint.data.toString())){ + clist.add(bPoint.data); + bPoint = bPoint.next; + continue; + } + if(Integer.parseInt(aPoint.data.toString())==Integer.parseInt(bPoint.data.toString())){ + clist.add(aPoint.data); + aPoint = aPoint.next; + bPoint = bPoint.next; + continue; + } + }//end While + while(aPoint!=null){ + clist.add(aPoint.data); + aPoint = aPoint.next; + } + while(bPoint!=null){ + clist.add(bPoint.data); + bPoint = bPoint.next; + } + return clist; + } } } diff --git a/group21/28394073/homework/src/com/coding/basic/LinkedListTest.java b/group21/28394073/homework/src/com/coding/basic/LinkedListTest.java new file mode 100644 index 0000000000..2ed671f4f6 --- /dev/null +++ b/group21/28394073/homework/src/com/coding/basic/LinkedListTest.java @@ -0,0 +1,295 @@ +package com.coding.basic; + +import static org.junit.Assert.*; +import junit.framework.Assert; + +import org.junit.Before; +import org.junit.Test; + +public class LinkedListTest { + + private LinkedList testList; + + private int initTestSize = 5; + + @Before + public void init() { +// 初始化的方法: + testList = new LinkedList(); + + for (int i = 0; i < initTestSize; i++) { + testList.add((Object)i); + } + testList.printLinkedList(); + + } + + + + @Test + public void testLinkedListIntArray() { + int[] arr = {1,3,5,8,100}; + LinkedList testList = new LinkedList(arr); //错误的原因是构造函数里面的head没有使用this + String expectedList = "1->3->5->8->100"; + Assert.assertEquals(expectedList, testList.printLinkedList()); + } + + @Test + public void testPrintLinkedList() { + //????????????? +// int[] arr = {}; +// LinkedList testList = new LinkedList(arr); +// Assert.assertNull(testList.printLinkedList()); + + int[] arr2 = {20}; + LinkedList testList2 = new LinkedList(arr2); + String expectedList2 = "20"; + Assert.assertEquals(expectedList2, testList2.printLinkedList()); + } + + @Test + public void testAddObject() { + testList.add(6); + testList.add(8); + String expectedList = "0->1->2->3->4->6->8"; + Assert.assertEquals(expectedList, testList.printLinkedList()); + } + + @Test + public void testAddIntObject() { + //测试ADD在尾部 + testList.add(5, 100); + String expectedList = "0->1->2->3->4->100"; + Assert.assertEquals(expectedList, testList.printLinkedList()); + //测试ADD在头部 + testList.add(0, 200); + String expectedList2 = "200->0->1->2->3->4->100"; + Assert.assertEquals(expectedList2, testList.printLinkedList()); + + //测试ADD在中间 + testList.add(3, 300); + String expectedList3 = "200->0->1->300->2->3->4->100"; + Assert.assertEquals(expectedList3, testList.printLinkedList()); + + //测试Add节点》链表size + Assert.assertFalse(testList.add(10, 1000)); + } + + @Test + public void testGet() { + Assert.assertNull(testList.get(7)); + Assert.assertEquals("0", testList.get(0).toString()); + Assert.assertEquals("3", testList.get(3).toString()); + Assert.assertEquals("4", testList.get(4).toString()); + } + + @Test + public void testRemoveInt() { + //测试删除头结点 + testList.remove(0); + String expectedList1 = "1->2->3->4"; + Assert.assertEquals(expectedList1, testList.printLinkedList()); + //测试删除尾节点 + testList.remove(3); + String expectedList2 = "1->2->3"; + Assert.assertEquals(expectedList2, testList.printLinkedList()); + //测试删除中间节点 + testList.remove(1); + String expectedList3 = "1->3"; + Assert.assertEquals(expectedList3, testList.printLinkedList()); + //测试删除的节点>链表SIZE + Assert.assertFalse("Error!Index larger than the size of Linkedlist", testList.remove(2)); + } + + @Test + public void testSize() { + //测试正常 + Assert.assertEquals(5, testList.size()); + //测试空链表 + LinkedList newList = new LinkedList(); //调用没有参数的构造函数 + Assert.assertEquals(0, newList.size()); + } + + @Test + public void testAddFirst() { + //测试正常 + testList.addFirst(100); + String expectedList1 = "100->0->1->2->3->4"; + Assert.assertEquals(expectedList1, testList.printLinkedList()); + //测试空链表 + LinkedList nullList = new LinkedList(); + nullList.addFirst(100); + String expectedList2 = "100"; + Assert.assertEquals(expectedList2,nullList.printLinkedList()); + + } + + @Test + public void testAddLast() { + //测试正常 + testList.addLast(100); + String expectedList1 = "0->1->2->3->4->100"; + Assert.assertEquals(expectedList1, testList.printLinkedList()); + //测试空链表 + LinkedList nullList = new LinkedList(); + nullList.addLast(100); + String expectedList2 = "100"; + Assert.assertEquals(expectedList2,nullList.printLinkedList()); + + } + + @Test + public void testRemoveFirst() { + //测试删除空链表 + LinkedList nullList = new LinkedList(); + Assert.assertFalse(nullList.removeFirst()); + //测试删除只有一个节点的链表 + LinkedList newList = new LinkedList(); + newList.add(100); + Assert.assertTrue(newList.removeFirst()); + //测试删除正常链表 + Assert.assertTrue(testList.removeFirst()); + String expectedResult = "1->2->3->4"; + Assert.assertEquals(expectedResult, testList.printLinkedList()); + } + + @Test + public void testRemoveLast() { + //测试删除空链表 + LinkedList nullList = new LinkedList(); + Assert.assertFalse(nullList.removeLast()); + //测试删除只有一个节点的链表 + LinkedList newList = new LinkedList(); + newList.add(100); + Assert.assertTrue(newList.removeLast()); + //测试删除正常链表 + Assert.assertTrue(testList.removeLast()); + String expectedResult = "0->1->2->3"; + Assert.assertEquals(expectedResult, testList.printLinkedList()); + } + +// @Test +// public void testIterator() { +// fail("Not yet implemented"); +// } + + @Test + public void testReverse() { + //测空链表 + LinkedList nullList = new LinkedList(); + nullList.reverse(); + Assert.assertEquals("", nullList.printLinkedList()); + //测只有一个节点的链表 + LinkedList list1 = new LinkedList(); + list1.add(100); + list1.reverse(); + Assert.assertEquals("100", list1.printLinkedList()); + //测正常链表 + testList.reverse(); + Assert.assertEquals("4->3->2->1->0", testList.printLinkedList()); + } + + @Test + public void testRemoveFirstHalf() { + int[] arr1 = {2,5,7,8}; + int[] arr2 = {2,5,7,8,10}; + String expected1 = "7->8"; + String expected2 = "7->8->10"; + LinkedList list1 = new LinkedList(arr1); + LinkedList list2 = new LinkedList(arr2); + list1.removeFirstHalf(); + list2.removeFirstHalf(); + Assert.assertEquals(expected1, list1.printLinkedList()); + Assert.assertEquals(expected2, list2.printLinkedList()); + + } + + @Test + public void testRemoveIntInt() { + //index+length>size + LinkedList nullList = new LinkedList(); + nullList.remove(3, 0); + Assert.assertEquals("", nullList.printLinkedList()); + //测试index大于等于size,且index+length又不大于size的 + testList.remove(5,0); + Assert.assertEquals("0->1->2->3->4", testList.printLinkedList()); + //remove后接起来的 + testList.remove(1, 2); + Assert.assertEquals("0->3->4", testList.printLinkedList()); + //remove后直接到尾部的 + testList.remove(1,2); + Assert.assertEquals("0", testList.printLinkedList()); + //只剩一个节点,但remove(0,0),即不删 + testList.remove(0,0); + Assert.assertEquals("0", testList.printLinkedList()); + //只剩一个节点,remove(1,0),出错 + testList.remove(1,0); + Assert.assertEquals("0", testList.printLinkedList()); + //只剩一个节点,remove(0,1),删 + testList.remove(0,1); + Assert.assertEquals("", testList.printLinkedList()); + } + + @Test + public void testGetElements() { + //测试溢出 + int[] arr1 = {11,101,201,301,401,501,601,701}; + LinkedList primeList = new LinkedList(arr1); + int[] arr2 = {0,3,6,8}; + LinkedList overflowList = new LinkedList(arr2); + Assert.assertNull(primeList.getElements(overflowList)); + //测试正常 + int[] arr3 = {0,3,6,7}; + LinkedList indexList = new LinkedList(arr3); + String expected = "11->301->601->701"; + int[] results = primeList.getElements(indexList); + //Junit是否提供两个数组直接作比较的函数呢? + String str_results = ""; + for(int i=0;i"; + + } + Assert.assertEquals(expected, str_results); + } + + @Test + public void testSubtract() { + int[] arr1 = {11,101,201,301,401,501,601,701}; + LinkedList primeList = new LinkedList(arr1); + int[] testlist = {0,1,2,3,11,15,16,18,201,300,301,500,600,601,602,700}; + LinkedList subList = new LinkedList(testlist); + primeList.subtract(subList); + Assert.assertEquals("101->401->501->701",primeList.printLinkedList()); + } + + @Test + public void testRemoveDuplicateValues() { + int[] arr1 = {11,11,201,301,301,501,601,701,701}; + LinkedList primeList = new LinkedList(arr1); + primeList.removeDuplicateValues(); + Assert.assertEquals("11->201->301->501->601->701", primeList.printLinkedList()); + } + + @Test + public void testRemoveRange() { + int[] testlist = {0,1,2,3,11,15,16,18,201,300,301,500,600,601,602,700}; + LinkedList primeList = new LinkedList(testlist); + primeList.removeRange(10,600); + Assert.assertEquals("0->1->2->3->601->602->700", primeList.printLinkedList()); + } + + @Test + public void testIntersection() { + int[] list1 = {0,1,3,5}; + LinkedList aList = new LinkedList(list1); + int[] list2 = {0,2,3,4,5,6}; + LinkedList bList = new LinkedList(list2); + LinkedList cList = aList.intersection(bList); + Assert.assertEquals("0->1->2->3->4->5->6", cList.printLinkedList()); + } + +} From 741b74542b2e801ab3997d277680a052bf43d795 Mon Sep 17 00:00:00 2001 From: liuyang Date: Thu, 30 Mar 2017 10:26:56 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9AAll(JVM+=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bin/com/coderising/litestruts/struts.xml | 11 ++ .../jvm/loader/ClassFileLoader.java | 76 ++++++++++ .../jvm/test/ClassFileloaderTest.java | 100 ++++++++++++++ .../com/coderising/jvm/test/EmployeeV1.java | 28 ++++ .../src/com/coding/basic/LRUPageFrame.java | 130 ++++++++++++++++++ .../com/coding/basic/LRUPageFrameTest.java | 77 +++++++++++ 6 files changed, 422 insertions(+) create mode 100644 group21/28394073/homework/bin/com/coderising/litestruts/struts.xml create mode 100644 group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group21/28394073/homework/src/com/coding/basic/LRUPageFrame.java create mode 100644 group21/28394073/homework/src/com/coding/basic/LRUPageFrameTest.java diff --git a/group21/28394073/homework/bin/com/coderising/litestruts/struts.xml b/group21/28394073/homework/bin/com/coderising/litestruts/struts.xml new file mode 100644 index 0000000000..6f23f0a83d --- /dev/null +++ b/group21/28394073/homework/bin/com/coderising/litestruts/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + \ No newline at end of file diff --git a/group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileLoader.java b/group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..8e8c23115c --- /dev/null +++ b/group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,76 @@ +package com.coderising.jvm.loader; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + + + +public class ClassFileLoader { + + private static final PrintStream err = null; + private static final int BUFFER_SIZE = 512; + + //这里为什么用数组保存路径?不用String? + //(ArrayList底层采用Object类型的数组实现,当使用不带参数的构造方法生成ArrayList对象时, + //实际上会在底层生成一个长度为10的Object类型数组。) + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws IOException { + byte[] buffer = new byte[BUFFER_SIZE]; + String classPath = className.replace(".", "\\"); + String path1=this.getClassPath() + "\\" +classPath+".class"; + System.out.print(path1); + FileInputStream is = new FileInputStream(path1); + BufferedInputStream bs = new BufferedInputStream(is); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int length=0; + while(true){ + int mul = 0; + length = bs.read(buffer); + if(length == BUFFER_SIZE){ + baos.write(buffer); + mul++; + } + if(length>0 && length Date: Tue, 11 Apr 2017 22:37:28 +0800 Subject: [PATCH 3/3] 0405Stack+JVM_Constant_Pool --- .../homework/src/com/coderising/jvm/Util.java | 24 +++ .../com/coderising/jvm/clz/AccessFlag.java | 25 +++ .../src/com/coderising/jvm/clz/ClassFile.java | 75 +++++++ .../com/coderising/jvm/clz/ClassIndex.java | 19 ++ .../coderising/jvm/constant/ClassInfo.java | 24 +++ .../coderising/jvm/constant/ConstantInfo.java | 29 +++ .../coderising/jvm/constant/ConstantPool.java | 29 +++ .../coderising/jvm/constant/FieldRefInfo.java | 54 +++++ .../jvm/constant/MethodRefInfo.java | 55 ++++++ .../jvm/constant/NameAndTypeInfo.java | 45 +++++ .../jvm/constant/NullConstantInfo.java | 13 ++ .../coderising/jvm/constant/StringInfo.java | 26 +++ .../com/coderising/jvm/constant/UTF8Info.java | 32 +++ .../jvm/loader/ByteCodeIterator.java | 51 +++++ .../jvm/loader/ClassFileLoader.java | 16 ++ .../jvm/loader/ClassFileParser.java | 119 +++++++++++ .../jvm/test/ByteCodeIteratorTest.java | 79 ++++++++ .../jvm/test/ClassFileloaderTest.java | 184 ++++++++++++++---- .../src/com/coding/basic/stack/Stack.java | 26 +++ .../src/com/coding/basic/stack/StackUtil.java | 145 ++++++++++++++ .../com/coding/basic/stack/StackUtilTest.java | 81 ++++++++ 21 files changed, 1110 insertions(+), 41 deletions(-) create mode 100644 group21/28394073/homework/src/com/coderising/jvm/Util.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/clz/AccessFlag.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/clz/ClassFile.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/clz/ClassIndex.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/constant/ClassInfo.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/constant/ConstantInfo.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/constant/ConstantPool.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/constant/FieldRefInfo.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/constant/MethodRefInfo.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/constant/NameAndTypeInfo.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/constant/NullConstantInfo.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/constant/StringInfo.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/constant/UTF8Info.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/loader/ByteCodeIterator.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileParser.java create mode 100644 group21/28394073/homework/src/com/coderising/jvm/test/ByteCodeIteratorTest.java create mode 100644 group21/28394073/homework/src/com/coding/basic/stack/Stack.java create mode 100644 group21/28394073/homework/src/com/coding/basic/stack/StackUtil.java create mode 100644 group21/28394073/homework/src/com/coding/basic/stack/StackUtilTest.java diff --git a/group21/28394073/homework/src/com/coderising/jvm/Util.java b/group21/28394073/homework/src/com/coderising/jvm/Util.java new file mode 100644 index 0000000000..0c4cc8c57c --- /dev/null +++ b/group21/28394073/homework/src/com/coderising/jvm/Util.java @@ -0,0 +1,24 @@ +package com.coderising.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes){ + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group21/28394073/homework/src/com/coderising/jvm/constant/FieldRefInfo.java b/group21/28394073/homework/src/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..65475e194c --- /dev/null +++ b/group21/28394073/homework/src/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group21/28394073/homework/src/com/coderising/jvm/constant/MethodRefInfo.java b/group21/28394073/homework/src/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..7f05870020 --- /dev/null +++ b/group21/28394073/homework/src/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group21/28394073/homework/src/com/coderising/jvm/constant/NameAndTypeInfo.java b/group21/28394073/homework/src/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..402f9dec86 --- /dev/null +++ b/group21/28394073/homework/src/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group21/28394073/homework/src/com/coderising/jvm/constant/NullConstantInfo.java b/group21/28394073/homework/src/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..936736016f --- /dev/null +++ b/group21/28394073/homework/src/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group21/28394073/homework/src/com/coderising/jvm/constant/StringInfo.java b/group21/28394073/homework/src/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..f1f8eb4ed4 --- /dev/null +++ b/group21/28394073/homework/src/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index; + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group21/28394073/homework/src/com/coderising/jvm/constant/UTF8Info.java b/group21/28394073/homework/src/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..bf2cc49d4d --- /dev/null +++ b/group21/28394073/homework/src/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool);//这里不理解 + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group21/28394073/homework/src/com/coderising/jvm/loader/ByteCodeIterator.java b/group21/28394073/homework/src/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..6f9c4dfaa5 --- /dev/null +++ b/group21/28394073/homework/src/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,51 @@ +package com.coderising.jvm.loader; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; + +import com.coderising.jvm.util.Util; + +public class ByteCodeIterator { + private int pos=0; + private byte[] byteCode; + + public ByteCodeIterator(byte[] byteCode){ + this.byteCode = byteCode; + } + + public int nextU1ToInt(){ + return Util.byteToInt(new byte[]{byteCode[pos++]}); + } + + public int nextU2ToInt(){ + return Util.byteToInt(new byte[]{byteCode[pos++],byteCode[pos++]}); + } + + public String nextU2ToHexString(){ + return Util.byteToHexString(new byte[]{byteCode[pos++],byteCode[pos++]}); + } + + public String nextU4ToHexString(){ + return Util.byteToHexString(new byte[]{byteCode[pos++],byteCode[pos++],byteCode[pos++],byteCode[pos++]}); + } + + public byte[] getBytes(int length){ + byte[] content = Arrays.copyOfRange(byteCode, pos, pos+length); + return content; + } + + public String getBytesToString(int length){ + byte[] content = Arrays.copyOfRange(byteCode, pos, pos+length); + pos = pos+length; + String str_content = null; + try { + str_content = new String(content,"UTF-8"); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return str_content; + } + + +} diff --git a/group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileLoader.java b/group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileLoader.java index 8e8c23115c..248f3d15fd 100644 --- a/group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileLoader.java +++ b/group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -10,6 +10,8 @@ import java.util.ArrayList; import java.util.List; +import com.coderising.jvm.clz.ClassFile; + public class ClassFileLoader { @@ -69,6 +71,20 @@ public String getClassPath(){ return finalPath; } + + public ClassFile loadClass(String className) { + // TODO Auto-generated method stub + ClassFileParser parser = new ClassFileParser(); + ClassFile clzFile = null; + try { + clzFile = parser.parse(this.readBinaryCode(className)); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return clzFile; + } + diff --git a/group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileParser.java b/group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..8b29fb80a9 --- /dev/null +++ b/group21/28394073/homework/src/com/coderising/jvm/loader/ClassFileParser.java @@ -0,0 +1,119 @@ +package com.coderising.jvm.loader; + +import java.io.UnsupportedEncodingException; + +import com.coderising.jvm.clz.AccessFlag; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.FieldRefInfo; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.NullConstantInfo; +import com.coderising.jvm.constant.StringInfo; +import com.coderising.jvm.constant.UTF8Info; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + ClassFile clzfile = new ClassFile(); + //Yang:首先判断二进制数组是否是java的class文件 + ByteCodeIterator iterator = new ByteCodeIterator(codes); + String magicNum = iterator.nextU4ToHexString(); + System.out.println(magicNum); + if(!magicNum.equals("cafebabe")){ + System.out.println("不是正确的java类文件"); + return null; + }else{ + clzfile.setMinorVersion(iterator.nextU2ToInt()); + clzfile.setMajorVersion(iterator.nextU2ToInt()); + + clzfile.setConstPool(this.parseConstantPool(iterator)); + + clzfile.setAccessFlag(this.parseAccessFlag(iterator)); + + clzfile.setClassIndex(this.parseClassInfex(iterator)); + + } + return clzfile; + + + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + AccessFlag acsFlag = new AccessFlag(iter.nextU2ToInt()); + return acsFlag; + } + + private ClassIndex parseClassInfex(ByteCodeIterator iter) { + ClassIndex clzIndex = new ClassIndex(); + clzIndex.setThisClassIndex(iter.nextU2ToInt()); + clzIndex.setSuperClassIndex(iter.nextU2ToInt()); + return clzIndex; + + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + + int constantPoolCount = iter.nextU2ToInt(); + System.out.println("常量池的个数:" + constantPoolCount); + + ConstantPool pool = new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo());//利用了空模式 + for(int i=1;i", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + } diff --git a/group21/28394073/homework/src/com/coding/basic/stack/Stack.java b/group21/28394073/homework/src/com/coding/basic/stack/Stack.java new file mode 100644 index 0000000000..fca69702fa --- /dev/null +++ b/group21/28394073/homework/src/com/coding/basic/stack/Stack.java @@ -0,0 +1,26 @@ +package com.coding.basic.stack; + +//import com.coding.basic.array.ArrayList;因为第一节课作业没做,所以这部分没实现 +import java.util.ArrayList; + + +public class Stack { + private ArrayList arr = new ArrayList(); + + public void push(Object o){ + } + + public Object pop(){ + return null; + } + + public Object peek(){ + return null; + } + public boolean isEmpty(){ + return false; + } + public int size(){ + return -1; + } +} diff --git a/group21/28394073/homework/src/com/coding/basic/stack/StackUtil.java b/group21/28394073/homework/src/com/coding/basic/stack/StackUtil.java new file mode 100644 index 0000000000..418db3d9a0 --- /dev/null +++ b/group21/28394073/homework/src/com/coding/basic/stack/StackUtil.java @@ -0,0 +1,145 @@ +package com.coding.basic.stack; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Stack; + +import com.coding.basic.LinkedList; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param + */ + public static void reverse(Stack s) { + LinkedList list = new LinkedList(); + while(!s.isEmpty()){ + list.add(s.pop()); + } + for(int i=0;i testStack,Object o) { + int index = testStack.search(o); + if(index == -1){//判断Object o是否在栈中,不在return + System.out.println("删除元素"+String.valueOf(o)+"不在栈中"); + return; + } + else{//Object o在栈中,remove + System.out.println("删除元素"+String.valueOf(o)+"的索引位置是Index=" + String.valueOf(index)); + //Remove操作 + Stack temp = new Stack(); + while(testStack.peek() != o){ + temp.push(testStack.pop()); + } + testStack.pop(); + while(!temp.empty()){ + testStack.push(temp.pop()); + } + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if(len>s.size()){//如果len>stack.size(),则return null; + System.out.println("溢出"); + return null; + } + else{ + Stack temp = new Stack(); + int len_temp = len; + int j = 0; + Object[] obj = new Object[len]; + while(len_temp--!=0){ + int val = s.pop(); + obj[j] = val; + j++; + temp.push(val); + } + while(!temp.empty()){ + s.push(temp.pop()); + } + + return obj; + } + } + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * @param s + * @return + */ + public static boolean isValidPairs(String s){ + Stack tempstack = new Stack(); + char[] charArr = s.toCharArray(); + for(char item:charArr){ + if(item=='(' || item=='[' || item=='{' ){ + tempstack.push(item); + continue; + } + switch(item){ + case ')': + if(tempstack.peek()=='('){ + tempstack.pop(); + }else{ + return false; + } + break; + case '}': + if(tempstack.peek()=='{'){ + tempstack.pop(); + }else{ + return false; + } + break; + case ']': + if(tempstack.peek()=='['){ + tempstack.pop(); + }else{ + return false; + } + break; + } + } + return true; + } + + public String printStack(java.util.Stack s){ + String str = ""; + if (s.empty()) + System.out.println("堆栈是空的,没有元素"); + else { + System.out.print("堆栈中的元素(从栈底到栈顶):"); +// Enumeration items = s.elements(); // 得到 stack 中的枚举对象 +// while (items.hasMoreElements()) //显示枚举(stack ) 中的所有元素 +// System.out.print(items.nextElement()+" "); + int count = 0; + for(int i:s){ + str = str + String.valueOf(i); + if(count++ != s.size()-1){ + str = str + ","; + } + } + } + System.out.println(str); + return str; + } + +} diff --git a/group21/28394073/homework/src/com/coding/basic/stack/StackUtilTest.java b/group21/28394073/homework/src/com/coding/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..6ae5c56618 --- /dev/null +++ b/group21/28394073/homework/src/com/coding/basic/stack/StackUtilTest.java @@ -0,0 +1,81 @@ +package com.coding.basic.stack; + +import static org.junit.Assert.*; +import java.util.Stack; + +import junit.framework.Assert; + +import org.junit.Before; +import org.junit.Test; + +public class StackUtilTest { + private static Stack testStack; + @Before + public void setup() throws Exception { + System.out.println("初始化堆栈:"); + testStack = new Stack(); + testStack.push(1); + testStack.push(2); + testStack.push(3); + testStack.push(4); + testStack.push(5); + StackUtil util = new StackUtil(); + util.printStack(testStack); + } + + @Test + public void testReverse() { + System.out.println("测试Stack反转:"); + StackUtil util = new StackUtil(); + util.reverse(testStack); + Assert.assertEquals("5,4,3,2,1", util.printStack(testStack)); + } + + @Test + public void testRemove() { + System.out.println("测试Stack删除:"); + StackUtil util = new StackUtil(); + util.remove(testStack, 8); + Assert.assertEquals("1,2,3,4,5",util.printStack(testStack)); + util.remove(testStack, 2); + Assert.assertEquals("1,3,4,5",util.printStack(testStack)); + + } + + @Test + public void testGetTop() { + System.out.println("测试获取Top len数据:"); + StackUtil util = new StackUtil(); + Object[] objArray1 = util.getTop(testStack, 9); + Assert.assertEquals(null, objArray1); + Assert.assertEquals("1,2,3,4,5", util.printStack(testStack)); + Object[] objArray2 = util.getTop(testStack, 3); + String actualStr = ""; + for(int i=0;i