@w1024020103
2017-03-12T23:46:31.000000Z
字数 6662
阅读 605
CS61B
UCBerkeley
Unit
test
Exceptions
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
.
/** Gets all column names that are common to both tables. */
public static String[] getCommonColumnNames(Table a, Table b){
String [] aColNames = a.colNames;
String [] bColNames = b.colNames;
ArrayList<String> commonColumnNames = new ArrayList<>();
for(int i = 0; i < aColNames.length; i++){
for(int j = 0; j < bColNames.length; j++){
if (aColNames[i].equals(bColNames[j])) {
commonColumnNames.add(aColNames[i]);
}
}
}
//Converting ArrayList to Array:
//List<String> list = ..;
//String[] array = list.toArray(new String[0]);
String[] commonColumnNamesInString = commonColumnNames.toArray((new String[0]));
return commonColumnNamesInString;
}
@Test
public void testGetCommonColumnNames() {
int anumOfCol = 2;
int anumOfRow = 3;
String[][] arowCol = new String[anumOfRow][anumOfCol];
String[] acolNames = new String[]{"X", "Y"};
String[] acolTypes = new String[]{"int", "int"};
Table a = new Table(acolNames, acolTypes, arowCol);
int bnumOfCol = 2;
int bnumOfRow = 3;
String[][] browCol = new String[bnumOfRow][bnumOfCol];
String[] bcolNames = new String[]{"X", "Z"};
String[] bcolTypes = new String[]{"int", "int"};
Table b = new Table(bcolNames, bcolTypes, browCol);
String[] expectedCommonColumnNames = {"X"};
String[] actualCommonColumnNames = Table.getCommonColumnNames(a, b);
assertArrayEquals(expectedCommonColumnNames, actualCommonColumnNames);
}
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.
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.
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.
It's RowDesc:
It's RDItems:
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 ;
.
/**
* @return
* An iterator which iterates over all the column RDItems
* that are included in this RowDesc
* */
public Iterator<RDItem> iterator() {
return new Iterator<RDItem>() {
int index = 0;
@Override
public boolean hasNext() {
return rdItemList.size() > 0;
}
@Override
public RDItem next() {
return rdItemList.get(index++);
}
};
}
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.7 之后我们有了@Rule
方法,就是下面的代码:
@Rule
public ExpectedException expectedEx = ExpectedException.none();
@Test
public void passwordIsEmptyThrowsException() throws InvalidPasswordException {
expectedEx.expect(InvalidPasswordException.class);
expectedEx.expectMessage("required");
Password.validate("");
}
上面代码需重点关注几个:
@Rule
注解的 ExpectedException
变量声明,它必须为 public
@Test
处,不能写成 @Test(expected=InvalidPasswordException.class)
,否则不能正确测试,也就是 @Test(expected=InvalidPasswordException.class)
和测试方法中的 expectedEx.expectXxx()
方法是不能同时并存的 expectedEx.expectMessage()
中的参数是 Matcher
或 subString
,就是说可用正则表达式判定,或判断是否包含某个子字符串 expectedEx.expectXxx()
方法后面,不然也不能正确测试的异常 I used @Rule ExpectedExcodeption method and test passed.
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.
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:
public enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7),
SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7),
NEPTUNE (1.024e+26, 2.4746e7);
private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
private double mass() { return mass; }
private double radius() { return radius; }
// universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;
double surfaceGravity() {
return G * mass / (radius * radius);
}
double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Usage: java Planet <earth_weight>");
System.exit(-1);
}
double earthWeight = Double.parseDouble(args[0]);
double mass = earthWeight/EARTH.surfaceGravity();
for (Planet p : Planet.values())
System.out.printf("Your weight on %s is %f%n",
p, p.surfaceWeight(mass));
}
}
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.
public enum Type {
INT ("int"),{}
STRING ("string"){}
public final String type;
Type(String type){
this.type = type;
}
For toString()
method, I got a brief understanding for String, StringBuffer, StringBuilder.
When writing the iterator of Row.java, I used Arrays.asList()
method for the first time.
/**
* @return
* An iterator which iterates over all the columns of this row
* */
public Iterator<Column> columns(){
// some code goes here
return Arrays.asList(columns).iterator();
}