[关闭]
@w1024020103 2017-03-12T23:46:31.000000Z 字数 6662 阅读 605

Proj2 RowDesc.java Row.java

CS61B UCBerkeley Unit test Exceptions


Join

when I write testGetCommonColumnNames(), one line is:
String[] actualCommonColumnNames = Table.getCommonColumnNames(a, b);
The method getCommonColumnNames(a, b) has to be utilized with the className.method.

  1. /** Gets all column names that are common to both tables. */
  2. public static String[] getCommonColumnNames(Table a, Table b){
  3. String [] aColNames = a.colNames;
  4. String [] bColNames = b.colNames;
  5. ArrayList<String> commonColumnNames = new ArrayList<>();
  6. for(int i = 0; i < aColNames.length; i++){
  7. for(int j = 0; j < bColNames.length; j++){
  8. if (aColNames[i].equals(bColNames[j])) {
  9. commonColumnNames.add(aColNames[i]);
  10. }
  11. }
  12. }
  13. //Converting ArrayList to Array:
  14. //List<String> list = ..;
  15. //String[] array = list.toArray(new String[0]);
  16. String[] commonColumnNamesInString = commonColumnNames.toArray((new String[0]));
  17. return commonColumnNamesInString;
  18. }
  1. @Test
  2. public void testGetCommonColumnNames() {
  3. int anumOfCol = 2;
  4. int anumOfRow = 3;
  5. String[][] arowCol = new String[anumOfRow][anumOfCol];
  6. String[] acolNames = new String[]{"X", "Y"};
  7. String[] acolTypes = new String[]{"int", "int"};
  8. Table a = new Table(acolNames, acolTypes, arowCol);
  9. int bnumOfCol = 2;
  10. int bnumOfRow = 3;
  11. String[][] browCol = new String[bnumOfRow][bnumOfCol];
  12. String[] bcolNames = new String[]{"X", "Z"};
  13. String[] bcolTypes = new String[]{"int", "int"};
  14. Table b = new Table(bcolNames, bcolTypes, browCol);
  15. String[] expectedCommonColumnNames = {"X"};
  16. String[] actualCommonColumnNames = Table.getCommonColumnNames(a, b);
  17. assertArrayEquals(expectedCommonColumnNames, actualCommonColumnNames);
  18. }

In fact, I didn't write static in getCommonColumnNames() method, but in that way I don't know how to use the method. I tried getCommonColumnNames(Table a ,Table b) doesn't work, but I should not initialize a new object to use this method, so I changed it to static that i could use the Class name to utilize it.

Later, I found that my codes are getting messy, and I consulted wechat study group that which data structure they used to implement the table, I got an answer says that he used HashMap and ArrayList. I think 2D array is too complicated when it comes to determine the joinedrows for two tables, So i decided to change my data structure and make things better.

Basic concepts about RDBMS

image_1baljpits4fd2upshdo4oc5p9.png-40kB

1.JPG-47kB

I was kind of stucked for a proper start, so I searched for similar work done by others and found an example simpleDB course work from CSE444 UW. I used the guideline for the coursework to build my database.

RowDesc.java Row.java

When working on RowDesc class which represents the row that has Name and Type, it has a instance variable ArrayList<RDItem> rdItemList to represent the whole row of items.RowDesc has a helper class RDItem which represents each field in RowDesc, RDItem has two instance variables:columnType and columnName.

For instance, here's a table.
屏幕快照 2017-03-08 下午8.31.01.png-29.4kB

It's RowDesc:
屏幕快照 2017-03-08 下午8.33.01.png-10.5kB

It's RDItems:
屏幕快照 2017-03-08 下午8.35.18.png-8.9kB
屏幕快照 2017-03-08 下午8.34.03.png-8.5kB
屏幕快照 2017-03-08 下午8.34.10.png-8.7kB

I practiced writing iterator again in this RowDesc class, this way of writing it could be applied whenever you need. Start with declaring public Iterator<Item> iterator(){}, and the first line within this method should be return new Iterator<Item>(){}, then you'll have to override the Iterator (its hasNext(), next()) in the new Iterator<Item>(){}, look at line 21 and remerber that this is all in your new() line which states that you are creating something, so you need to end with ;.

  1. /**
  2. * @return
  3. * An iterator which iterates over all the column RDItems
  4. * that are included in this RowDesc
  5. * */
  6. public Iterator<RDItem> iterator() {
  7. return new Iterator<RDItem>() {
  8. int index = 0;
  9. @Override
  10. public boolean hasNext() {
  11. return rdItemList.size() > 0;
  12. }
  13. @Override
  14. public RDItem next() {
  15. return rdItemList.get(index++);
  16. }
  17. };
  18. }

There's a unit test that never passes when implementing RowDescTest.java, I actually have never written Unit tests for Exceptions therefore I did some reading on it.

JUnit 4 如何正确测试异常

自 JUnit 4.7 之后我们有了@Rule方法,就是下面的代码:

  1. @Rule
  2. public ExpectedException expectedEx = ExpectedException.none();
  3. @Test
  4. public void passwordIsEmptyThrowsException() throws InvalidPasswordException {
  5. expectedEx.expect(InvalidPasswordException.class);
  6. expectedEx.expectMessage("required");
  7. Password.validate("");
  8. }

上面代码需重点关注几个:

  1. @Rule 注解的 ExpectedException 变量声明,它必须为 public
  2. @Test 处,不能写成 @Test(expected=InvalidPasswordException.class),否则不能正确测试,也就是 @Test(expected=InvalidPasswordException.class) 和测试方法中的 expectedEx.expectXxx()方法是不能同时并存的
  3. expectedEx.expectMessage() 中的参数是 MatchersubString,就是说可用正则表达式判定,或判断是否包含某个子字符串
  4. 再就是有一点很重,把被测试方法写在 expectedEx.expectXxx() 方法后面,不然也不能正确测试的异常
  5. 最后一个是,只要测试方法直接抛出被测试方法的异常即可,并不影响你所关心的异常

I used @Rule ExpectedExcodeption method and test passed.
屏幕快照 2017-03-08 下午10.38.12.png-112.7kB

However if i squencially write the two sets of expectedEX.ex together, test failed. I think this is because the first expectedEX.ex may take rd.columnNameToIndex("") into consideration besides its own rd.columnNameToIndex("cool")because it take method that written behind expectedEx.expectXxx() into consideration. But I may just end here it's not a major topic for this project.
屏幕快照 2017-03-08 下午10.41.47.png-182.4kB

Then I modified Enum Type in my Type.java, here I got a brief understanding of Enums in Java.
Enum Types

Planet has methods that allow you to retrieve the surface gravity and weight of an object on each planet. Here is a sample program that takes your weight on earth (in any unit) and calculates and prints your weight on all of the planets (in the same unit):

Here's an example:

  1. public enum Planet {
  2. MERCURY (3.303e+23, 2.4397e6),
  3. VENUS (4.869e+24, 6.0518e6),
  4. EARTH (5.976e+24, 6.37814e6),
  5. MARS (6.421e+23, 3.3972e6),
  6. JUPITER (1.9e+27, 7.1492e7),
  7. SATURN (5.688e+26, 6.0268e7),
  8. URANUS (8.686e+25, 2.5559e7),
  9. NEPTUNE (1.024e+26, 2.4746e7);
  10. private final double mass; // in kilograms
  11. private final double radius; // in meters
  12. Planet(double mass, double radius) {
  13. this.mass = mass;
  14. this.radius = radius;
  15. }
  16. private double mass() { return mass; }
  17. private double radius() { return radius; }
  18. // universal gravitational constant (m3 kg-1 s-2)
  19. public static final double G = 6.67300E-11;
  20. double surfaceGravity() {
  21. return G * mass / (radius * radius);
  22. }
  23. double surfaceWeight(double otherMass) {
  24. return otherMass * surfaceGravity();
  25. }
  26. public static void main(String[] args) {
  27. if (args.length != 1) {
  28. System.err.println("Usage: java Planet <earth_weight>");
  29. System.exit(-1);
  30. }
  31. double earthWeight = Double.parseDouble(args[0]);
  32. double mass = earthWeight/EARTH.surfaceGravity();
  33. for (Planet p : Planet.values())
  34. System.out.printf("Your weight on %s is %f%n",
  35. p, p.surfaceWeight(mass));
  36. }
  37. }

Defining a enum is no different from defining any other class.
Because they are constants, the names of an enum type's fields are in uppercase letters.

In the Java programming language, you define an enum type by using the enum keyword.
So I modified my Type.java as below that I can print int and string in toString() in RowDesc.java by calling rdItemList.columnType.type to match the output format of the table.

  1. public enum Type {
  2. INT ("int"),{}
  3. STRING ("string"){}
  4. public final String type;
  5. Type(String type){
  6. this.type = type;
  7. }

For toString() method, I got a brief understanding for String, StringBuffer, StringBuilder.

浅谈 Java 字符串

When writing the iterator of Row.java, I used Arrays.asList() method for the first time.

  1. /**
  2. * @return
  3. * An iterator which iterates over all the columns of this row
  4. * */
  5. public Iterator<Column> columns(){
  6. // some code goes here
  7. return Arrays.asList(columns).iterator();
  8. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注