Working with arrays can be a bit frustrating after the freedom of Python lists, but it's important to be aware of how they work. If you want all the functionality of Python lists, you really want to use an ArrayList in Java (instead of an array). Here's an example of an ArrayList in action:
public static void main(String[] args) {
System.out.println("Hello, World!");
ArrayList list = new ArrayList();
list.add(5);
list.add("Hello there!");
list.add(6 == 4);
System.out.println(list);
}
Compile this code. If the compiler is complaining about not knowing what an ArrayList is, it means you need to add the import statement to the top of your code:
import java.util.*;
Once you get that working, you'll see a new warning message:
$ javac *.java
Note: CodeToRun.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
$
This is not an error: the code has compiled successfully. The compiler, however, is extremely concerned with type safety, and it's letting you know that some of the operations you've written could cause an exception due to the types of values added to list. There is a way to eliminate this error, which we'll see soon, though it will also restrict the types of values we can add to the list.
For now, let's enjoy the benefits of ArrayLists:
Let's go more closely over the different operations. At some point you might want to look over the ArrayList API.
ArrayList fishMonkey = new ArrayList();
That's it. When you put the keyword new before a classname followed by parentheses (and possibly arguments), then you're calling a constructor, which creates a new instance of that class. This is just like Python, except that you need the new keyword. Python allows you to be a bit more flexible in creating lists in one line, so this may take some getting used to.
ArrayList.addPython's append method becomes the add method. We saw an example of this already. Let's keep moving!
setsome_list[5] = "beluga whale" becomes someList.set(5, "beluga whale");
ArrayList.getmighty_mouse = some_list[3] becomes Object mightyMouse = someList.get(3); Here's some code extending on the previous example that uses get and set:
ArrayList list = new ArrayList();
list.add(5);
list.add("Hello there!");
list.add(6 == 4);
System.out.println("list: " + list);
Object number = list.get(0);
list.set(0, number + 3);
System.out.println("list: " + list);
Unfortunately, this doesn't compile successfully:
$ javac *.java
CodeToRun.java:13: error: bad operand types for binary operator '+'
list.set(0, number + 3);
^
first type: Object
second type: int
Note: CodeToRun.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
$
Java doesn't know how to use the + operator between an object and an integer. There are really two things at play here:
Integer instead of an int. This happens because everything inside of an ArrayList must be an object. Java automatically "wraps" the primitive integer 5 in an Integer object at the list.add(5); line.list when list.get(0) is invoked. All it knows is that it is an object, and thus the type of that value must be some subtype of Object. Java doesn't know how to add Object values to integers, so it can't compile that line.What can we do about this? Well, we can create a new variable with the desired type and type cast the value:
ArrayList list = new ArrayList();
list.add(5);
list.add("Hello there!");
list.add(6 == 4);
System.out.println("list: " + list);
Object number = list.get(0);
Integer x = (Integer) number;
list.set(0, x + 3);
System.out.println("list: " + list);
Try to compile and run this:
$ javac *.java
Note: CodeToRun.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
cspc05:web kgb1013$ java CodeToRun
Hello, World!
list: [5, Hello there!, false]
list: [8, Hello there!, false]
$
It works! The expression (Integer) number performs the type cast. This does not change the type of the variable number! number is still has type Object. We can forego creating the new x variable and do the typecast inside the argument expression for set:
ArrayList list = new ArrayList();
list.add(5);
list.add("Hello there!");
list.add(6 == 4);
System.out.println("list: " + list);
Object number = list.get(0);
list.set(0, ((Integer) number) + 3);
System.out.println("list: " + list);
Notice that the parentheses are needed around the new type.
What do you think will happen if we change the zeroeth element to be a string?
ArrayList list = new ArrayList();
list.add("bonanza");
list.add("Hello there!");
list.add(6 == 4);
System.out.println("list: " + list);
Object number = list.get(0);
list.set(0, ((Integer) number) + 3);
System.out.println("list: " + list);
We get a ClassCastException:
$ java CodeToRun Hello, World! list: [bonanza, Hello there!, false] Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at CodeToRun.main(CodeToRun.java:13) $
"bonanza" couldn't be cast into an Integer because Java doesn't know how to do that conversion. Generally you want to do as little typecasting as possible, in order to avoid these errors. Soon we'll see how to use get without needing to any casting.
ArrayList.sizelen(some_list) becomes someList.size(). We can use this in a for loop to print out the elements of a list on different lines.
ArrayList list = new ArrayList();
list.add("bonanza");
list.add("Hello there!");
list.add(6 == 4);
System.out.println("list: " + list);
for (int i = 0; i < list.size(); i++) {
System.out.println("list[" + i + "]: " + list.get(i));
}
There are lots of other ArrayList methods. Go check out the ArrayList API.
Change your Monkey class to use ArrayLists of strings instead of arrays. You'll have to modify both the main method and the static printMonkey method.