XMLing in Java? Use java-xmlbuilder
XML is not native to Java. Many will disagree, but this is just the simple truth. It’s tedious, messy and generally ugly – specially compares to Groovy or Scala.
However, if you DO need to use XML in Java, do yourself a favour and use java-xmlbuilder. I’ve tried it on easy-weight tasks, and it’s by far the simplest most straight-forward XML tool for Java I’ve used so far.
Enjoy!
Beware of Doubles, Floats, and generally floating points…
I’ve recently encountered few people who were naive about the representations of real (i.e not integers) numbers in computer languages , like double and float in Java (and their counterparts in other languages).
Since examples are worth much more then explanations, lets looks at this:
double y = 0.082;
double z = 8.2;
System.out.println("" + y +" * 100 = " + z + "? " +
(100 * y == z) + " it equals " + (100 * y) );
and the output is:
0.082 * 100 = 8.2? false it equals 8.200000000000001
The next example shows exactly why you should be wary of floating points. Look at the binary representation after each iteration.
public static void main(String[] args) {
Double x = 1.0 / 3.0;
for (int i=0; i= 1) {
System.out.println("Iteration: " + i + " x = " + x);
System.out.println("Binary representation: " +
Long.toBinaryString(Double.doubleToRawLongBits(x)));
x = x * 2;
if (x >= 1) {
x = x - 1;
}
}
}
Iteration: 0 x = 0.3333333333333333
Binary representation: 11111111010101010101010101010101010101010101010101010101010101
Iteration: 1 x = 0.6666666666666666
Binary representation: 11111111100101010101010101010101010101010101010101010101010101
Iteration: 2 x = 0.33333333333333326
Binary representation: 11111111010101010101010101010101010101010101010101010101010100
Iteration: 3 x = 0.6666666666666665
Binary representation: 11111111100101010101010101010101010101010101010101010101010100
Iteration: 4 x = 0.33333333333333304
Binary representation: 11111111010101010101010101010101010101010101010101010101010000
Iteration: 5 x = 0.6666666666666661
Binary representation: 11111111100101010101010101010101010101010101010101010101010000
Iteration: 6 x = 0.33333333333333215
Binary representation: 11111111010101010101010101010101010101010101010101010101000000
Iteration: 7 x = 0.6666666666666643
Binary representation: 11111111100101010101010101010101010101010101010101010101000000
Iteration: 8 x = 0.3333333333333286
Binary representation: 11111111010101010101010101010101010101010101010101010100000000
Iteration: 9 x = 0.6666666666666572
Binary representation: 11111111100101010101010101010101010101010101010101010100000000
Iteration: 10 x = 0.3333333333333144
Binary representation: 11111111010101010101010101010101010101010101010101010000000000
Iteration: 11 x = 0.6666666666666288
Binary representation: 11111111100101010101010101010101010101010101010101010000000000
Iteration: 12 x = 0.33333333333325754
Binary representation: 11111111010101010101010101010101010101010101010101000000000000
Iteration: 13 x = 0.6666666666665151
Binary representation: 11111111100101010101010101010101010101010101010101000000000000
Iteration: 14 x = 0.33333333333303017
Binary representation: 11111111010101010101010101010101010101010101010100000000000000
Iteration: 15 x = 0.6666666666660603
Binary representation: 11111111100101010101010101010101010101010101010100000000000000
Iteration: 16 x = 0.3333333333321207
Binary representation: 11111111010101010101010101010101010101010101010000000000000000
Iteration: 17 x = 0.6666666666642413
Binary representation: 11111111100101010101010101010101010101010101010000000000000000
Iteration: 18 x = 0.3333333333284827
Binary representation: 11111111010101010101010101010101010101010101000000000000000000
Iteration: 19 x = 0.6666666666569654
Binary representation: 11111111100101010101010101010101010101010101000000000000000000
Iteration: 20 x = 0.3333333333139308
Binary representation: 11111111010101010101010101010101010101010100000000000000000000
Iteration: 21 x = 0.6666666666278616
Binary representation: 11111111100101010101010101010101010101010100000000000000000000
Iteration: 22 x = 0.3333333332557231
Binary representation: 11111111010101010101010101010101010101010000000000000000000000
Iteration: 23 x = 0.6666666665114462
Binary representation: 11111111100101010101010101010101010101010000000000000000000000
Iteration: 24 x = 0.3333333330228925
Binary representation: 11111111010101010101010101010101010101000000000000000000000000
Iteration: 25 x = 0.666666666045785
Binary representation: 11111111100101010101010101010101010101000000000000000000000000
Iteration: 26 x = 0.3333333320915699
Binary representation: 11111111010101010101010101010101010100000000000000000000000000
Iteration: 27 x = 0.6666666641831398
Binary representation: 11111111100101010101010101010101010100000000000000000000000000
Iteration: 28 x = 0.3333333283662796
Binary representation: 11111111010101010101010101010101010000000000000000000000000000
Iteration: 29 x = 0.6666666567325592
Binary representation: 11111111100101010101010101010101010000000000000000000000000000
Iteration: 30 x = 0.3333333134651184
Binary representation: 11111111010101010101010101010101000000000000000000000000000000
Iteration: 31 x = 0.6666666269302368
Binary representation: 11111111100101010101010101010101000000000000000000000000000000
Iteration: 32 x = 0.33333325386047363
Binary representation: 11111111010101010101010101010100000000000000000000000000000000
Iteration: 33 x = 0.6666665077209473
Binary representation: 11111111100101010101010101010100000000000000000000000000000000
Iteration: 34 x = 0.33333301544189453
Binary representation: 11111111010101010101010101010000000000000000000000000000000000
Iteration: 35 x = 0.6666660308837891
Binary representation: 11111111100101010101010101010000000000000000000000000000000000
Iteration: 36 x = 0.3333320617675781
Binary representation: 11111111010101010101010101000000000000000000000000000000000000
Iteration: 37 x = 0.6666641235351562
Binary representation: 11111111100101010101010101000000000000000000000000000000000000
Iteration: 38 x = 0.3333282470703125
Binary representation: 11111111010101010101010100000000000000000000000000000000000000
Iteration: 39 x = 0.666656494140625
Binary representation: 11111111100101010101010100000000000000000000000000000000000000
Iteration: 40 x = 0.33331298828125
Binary representation: 11111111010101010101010000000000000000000000000000000000000000
Iteration: 41 x = 0.6666259765625
Binary representation: 11111111100101010101010000000000000000000000000000000000000000
Iteration: 42 x = 0.333251953125
Binary representation: 11111111010101010101000000000000000000000000000000000000000000
Iteration: 43 x = 0.66650390625
Binary representation: 11111111100101010101000000000000000000000000000000000000000000
Iteration: 44 x = 0.3330078125
Binary representation: 11111111010101010100000000000000000000000000000000000000000000
Iteration: 45 x = 0.666015625
Binary representation: 11111111100101010100000000000000000000000000000000000000000000
Iteration: 46 x = 0.33203125
Binary representation: 11111111010101010000000000000000000000000000000000000000000000
Iteration: 47 x = 0.6640625
Binary representation: 11111111100101010000000000000000000000000000000000000000000000
Iteration: 48 x = 0.328125
Binary representation: 11111111010101000000000000000000000000000000000000000000000000
Iteration: 49 x = 0.65625
Binary representation: 11111111100101000000000000000000000000000000000000000000000000
Iteration: 50 x = 0.3125
Binary representation: 11111111010100000000000000000000000000000000000000000000000000
Iteration: 51 x = 0.625
Binary representation: 11111111100100000000000000000000000000000000000000000000000000
Iteration: 52 x = 0.25
Binary representation: 11111111010000000000000000000000000000000000000000000000000000
Iteration: 53 x = 0.5
Binary representation: 11111111100000000000000000000000000000000000000000000000000000
Iteration: 54 x = 0.0
Binary representation: 0
Why does it happen?
Because if you use 64 bits to store a floating point number, you use 1 for the sign (+/-), 11 for the mantissa, and 52 for the value itself. And after adding 52 trailing zeroes …
In each deduction we remove the msb (most significan bit) and add a trailing 0 as a lsb (least significant bit) – and that’s – in a nutshell – what kills our precision. Naturally, there are ways to get over it, but you should be aware that you need to use these methods.
You can read more about it here:
http://kipirvine.com/asm/workbook/floating_tut.htm
http://support.microsoft.com/kb/42980
http://en.wikipedia.org/wiki/Single-precision_floating-point_format
Comparison method violates its general contract!
java.lang.IllegalArgumentException: Comparison method violates its general contract!
Well, this is definitely the weirdest Java exception I’ve had so far. I got it on a Comparator I wrote, which returned either -1 or 1 (no == check was performed , and I never returned 0) .
This will happen to you usually when switching to Java 7 from older versions of Java. (Happened to me when I switched from 6 to 7)
Long story short , the solution was to add the following line (Which is generally a good idea) to your Comparator :
if (o1 == o2) return 0;
Why does it happens ? Well, according to Java 7 change set, they replaced the merge sort implementation , and from now on
The new sort implementation may throw an IllegalArgumentException if it detects a Comparable that violates the Comparable contract.
Why is that important to them? I have no idea, but I’m guessing maybe the new merge sort works better when some elements are equal (i.e , the compartor returns 0), and having a “bad” comprator hinders performances. .
What I do fail to understand is why this contract validity test done on runtime and not on compilation time!
Concurrency in Java – Hashes, hashes of lists, ConcurrentHashMap, CopyOnWriteArrayList and Guava
This post is mainly about using hash and hash-like structures in a multi threaded app. You might want to consider reading about Callable and other approaches too.
First thing you should know about concurrency – it’s not simple. It’s never simple, and although the built-in structures might help you, you’ll still need to make sure that your solution is robust.
My problem was this: I needed to have a hash of String –> List<String> , and update the list. Something like this:
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (Doc d : docs) {
List<Doc> l = map.get(doc.getId());
if (l == null) {
l = new ArrayList<Doc>();
map.put(doc.getId(),l);
}
l.add(d);
}
Naturally , this will only work in single threaded environment. But my environment is a multithreaded environment. So what do we do?
Well , the first, simplest solution is to just use a SynchronizedMap. This will work, but it will slow down your application immensely – It’s basically wrapping your map with a lock, and limiting access based on the lock. Which is a good enough solution if speed is not an issue, but otherwise it’s a bit crippling.
The second simplest solution is to use ConcurrentMap. So we just replace our map with a ConcurrentHashMap.
We’ll ConcurrentHashMap is basically a map with a lot of locks (default is 16). That way, the buckets in the map are distributed to super-bucket themselves , and each super-bucket is protected via a lock. That way, you get much more access to the hash then in the Synchronized case.
Map<String, List<String>> map = new ConcurrentHashMap<String, List<String>>();
for (Doc d : docs) {
List<Doc> l = map.get(doc.getId())
if (l == null) {
l = new ArrayList<Doc>()
map.put(doc.getId(),l)
}
l.add(d)
}
However, we are still at risk of losing data due to a race condition: if we have 2 threaded that are trying to insert different document (d1, d2) with the same id to the hash in the same time , and the id is not yet there , then both of them might access the hash, see that there is value for that id, create a new, empty ArrayList, and then commit one right after the other – which means that we will lose one of the documents.
So, what do we do?
We’re going to use a very important function provided called “putIfAbsent”. It basically just does this :
if (!map.containsKey(key))
return map.put(key, value);
else
return map.get(key);
but does it atomically. So if we’d change our code to reflect that :
Map<String, List<String>> map = new ConcurrentHashMap<String, List<String>>();
for (Doc d : docs) {
List<Doc> l = new ArrayList<Doc>()
List<Doc> cur = map.putIfAbsent(doc.getId(),l)
if (cur == null) {
l.add(d)
} else {
cur.add(d)
}
}
What “putIfAbsent” returns is “what was in the list when I got there” . If it returns “null” , then the list we’ve provided , l, was placed in the hash a the value of our Id. Otherwise, there was already a list there, and we will have to use it (cur).
O.K, so that solves the problem of several threads overriding each other when creating a new list.
However, there’s a big chance that you’ll fail due to ConcurrentModificationException. Why is that?
The reason for that is because we are constantly changing the values in the ArrayList – and if you’re going to iterate over the list at that point or another while some threads are still working on it, you’re most definitely going to have ConcurrentModificationException.
So, what to do?
Well, I guess there are multiple ways to take care of it, but in my case , since the number of Docs per id is limited to few dozens, I choose to work with the CopyOnWriteArrayList . Basically what it does is this : every time you create an iterator of the list, the iterator has a “snapshot” of the list-state on the moment of it’s creation. That way, you will never have a ConcurrentModificationException. So the new code is :
Map<String, CopyOnWriteArrayList<String>> map = new ConcurrentHashMap<String, CopyOnWriteArrayList<String>>();
for (Doc d : docs) {
List<Doc> l = new CopyOnWriteArrayList <Doc>()
List<Doc> cur = map.putIfAbsent(doc.getId(),l)
if (cur == null) {
l.add(d)
} else {
cur.add(d)
}
}
Two last notes about concurrency in Java:
The first is that if you find yourself buried deep in concurrency issues, you might want to think about changing your strategy from synchronizing and concurrency to actors and callables.
The second is this – if you’re already creating specialized structures for your application – start thinking about using Guava - google’s open source concurrency package.
SearchIndexer & TSVNCache : Two things that are hogging your hd – and your computer
I have a brand new Lenovo T510 , i7, 4G ,64bit , Windows 7 with an Nvidia GPU – and it sucks. In this price , with these specifications , it really shouldn’t suck.
I’ve tried numerous things (including the regular defrag scan disk sequence) , and I did find a few problems (It was utilizing only 3 GB out of 4 , for example) – But it still sometimes had the worst performances ever.
I then noticed the my Hard drive icon is constantly flashing , even when I do no intense IO operations. It’s just always on. So I started searching for my HD hogger, and I found these two:
- SearchIndexer.exe – This one is all MS fault. It’s the MS file indexer on Windows 7 . Now , I really like the new “look for a command name instead of searching the damn thing in tens of application” , but why does it have to hog my HD all the time? It was accessing my hd ALL THE TIME! .
This is how you make it go away. Basically , it’s a service , so you just run the services.msc and stop it (and then kill it from the task manager). - TSVNCache.exe – This one only applies if you use the Tortoise SVN client. (If you have no idea what this is , you probably don’t have it) . Apperantly , the Tortoise client really wants to be helpful , so it just keep scanning your entire hd to refresh the SVN icon on your files. This is such an over kill , as most of your folders aren’t managed by the svn. So this is how you make it stop crunching your hd , and only running where it should
My computer HD is now 90% lower on avg, and it actually feels like a good machine to have.
Scala 101 – Named & Default parameters
Another syntax sugar provided in Scala are the default values for parameters , and the named parameters. Its fairly stright forwards , so We’ll just start with an example :
def f(age: Int, name: String = "MyName") = println ("Hello, " + name + " , you're "
+ age + " years old")
f: (age: Int,name: String) Unit
scala> f (1)
Hello, MyName , you're 1 years old
scala> f (1,"Jaws")
Hello, Jaws , you're 1 years old
So we just gave the parameter a default value , and if we don’t provide a value , it just takes the default. That’s very nice. But what will happen in the following case?
def f(name: String = "MyName", age: Int) = println ("Hello, " + name + " , you're " + age + " years old")
f: (name: String,age: Int) Unit
scala> f(1)
<console>:7: error: not enough arguments for method f: (name: String,age: Int)Unit.
Unspecified value parameter age.
f(1)
Well, this doesn’t work . Why? because the compiler can’t tell which argument you meant. One solution is to put all the default parameters at the end of the function:
def f(age: Int, name:String = "MyName") = println ("Hello, " + name + " , you're " + age + " years old")
f: (age: Int,name: String)Unit
scala> f(1)
Hello, MyName , you're 1 years old
Another , and better, option is to just call them by their names:
def f(name: String = "MyName", age: Int) = println ("Hello, " + name + " , you're " + age + " years old")
f: (name: String,age: Int)Unit
scala> f(age=1)
Hello, MyName , you're 1 years old
I feel like this entire thing is a syntactic sugar , but it’s still a nice one
Scala 101 – Scoping
This is a part of my Scala tutorial . Read the first part & second part for a more general Scala intro. You can read here for an overview of how to write a class in Scala.
Scoping
Like in most OO languages, you can limit the access to certain elements of the class (fields, methods) using access level modifiers – private , public , protected are the basic ones , but you can also have the package scope in Java , and the “friend” class in C++
Scala supports something much more agile then what we’ve come to expect : As usual , you have private , protected and public (which is default in Scala , unlike in Java) – But , and this is where the fun begins , you also have a variable scope . Let’s see an example , as usual , with our Fish class:
Let’s say we have 2 fish : smallFish and bigFish. Currently , they can access each other’s private field “myName” :
scala> var smallFish = new Fish("Small")
smallFish: Fish = Fish@5cb27de5
scala> var bigFish = new Fish("Big")
bigFish: Fish = Fish@78bdf2a
scala> bigFish.sayHello(smallFish)
hello, Small
scala> smallFish.sayHello(bigFish)
hello, Big
This is unavoidable in Java – The “private” modifier is valid for the class , not each object. It’s like a small community – everyone who is like you (i.e object of the same class) can access everything you have.
Let’s see how Scala solves this :
private[this] var myName = fishName
What we’ve done is added the “[this]” to the “private” access modifier – and that means that this variable is only usable from this object only. Let’s see what happens when we try to compile the class with this small change:
class Fish (var fishName: String){
private[this] var myName = fishName
def name = myName
def name_= (newName: String) = myName = newName
def sayHello(otherFish : Fish) = println ("hello, " + otherFish.myName)
}
<console>:11: error: value myName is not a member of Fish
def sayHello(otherFish : Fish) = println ("hello, " + otherFish.myName)
So the class won’t even compile – exactly like it won’t compile if you try to access a private field from outside the class.
What else can you write in the [scope] ?
Here is what Oreilly has to say about it :
Visibility is limited to [scope], which can be a package, type, or this (meaning the same instance, when applied to members, or the enclosing package, when applied to types).
Scala 101 – OOP : Getters & Setters
This is a part of my Scala tutorial . Read the first part & second part for a more general Scala intro. You can read here for an overview of how to write a class in Scala.
Let’s say we have the following class:
class Fish {
var name = "Default Name"
}
scala> var jaws = new Fish
jaws: Fish = Fish@8191a42
scala> jaws.name
res29: java.lang.String = Default Name
scala> jaws.name = "Jaws"
scala> jaws.name
res30: java.lang.String = Jaws
Now , let’s say you’ve decided you need to limit access to the name parameter vis a setter and a getter. How would those functions look like? Well , if you come from Java , like me , you would probably do something like this (after adding the “private” modifier to the variable):
And then you can use it like this:
scala> var jaws = new Fishjaws: Fish = Fish@1f619137
scala> jaws.getName
res32: java.lang.String = Default
scala> jaws.setName("Jaws")
scala> jaws.getName
res34: java.lang.String = Jaws
Problem Solved ? Well , this solution will work , but it’s crappy. Why is it crappy?
- You broke your api
- If you want to avoid breaking the api , you have to have getters/setters from step one – which is a lot of unnecessary code , and it’s really not very elegant.
- It’s much less convenient then the previous way.
So here comes Scala to the rescue: First , lets change the field name from “name” to “myName”. Now , the Getter : lets create a function called “name” that will return the value of “myName”. It fairly easy:
//Getter def name = myName
You don’t have to use “return” in Scala , and if it’s a one-liner , you can drop the {} , so we get a lovely little function that we can use like this :
scala> jaws.name res30: java.lang.String = Jaws
Now for the setter. What we would like to do is keep the convenient field access – if we can get the name by using “jaws.name” , it would be great if we could have a function that will enable us to do this :
jaws.name = "Jaws"
//Setter def name_= (newName: String) = myName = newName
scala> var jaws = new Fishjaws: Fish = Fish@8191a42 scala> jaws.name res29: java.lang.String = Default Name scala> jaws.name = "Jaws" scala> jaws.name res30: java.lang.String = Jaws
Scala 101– Basic OOP : Writing a class
This is part 3 of my Scala tutorial – read the first part and the second part for a more general Scala intro. All the examples you see here were ran via the REPL ( that’s the Scala interpreter).
Scala’s take on OOP:
Scala tends toward pure object oriented model:
In Java , You have Objects and Primitives. Scala , on the other hand , takes after other language like Python, Ruby, Smalltalk (and many others) in the sense that Everything is an object. Including the integer 1 and string “Hello, World”. For many , this seems a reasonable evolution from the Object/Primitive dichotomy used in Java.
This is something people with no background in functional programming sometimes find difficult to accept in the beginning.
In Scala , a function is just another type of object , and as such it do anything an object can – Change , get sent as a parameter , be the return value of another function , and so forth. Even though the idea seems strange at first , you might recall that even in C/C++ you can pass a reference to a function , or use it as a return value from a function.
Let’s get technical:
Let’s build a simple class that will represent a fish. At first , a fish only has a name:
scala> class Fish(var name: String) {}
defined class Fish
Well , something looks a bit… off… , isn’t it? There’s no constructor , no fields , no nothing! And yet , it works:
scala> var jaws = new Fish("Jaws")
jaws: Fish = Fish@530f243b
scala> jaws.name
res2: String = Jaws
scala> jaws.name = "Rex"
scala> jaws.name
res3: String = Rex
So what happened here , exactly? What we’ve used here is the “Primary Constructor”. The variable we’ve passed is a property of the class , and you really don’t need any more setters and getters.
What if I want an immutable field? Just use “val” instead of “var” :
scala> class Fish(val name: String) {}
defined class Fish
scala> var jaws = new Fish("Jaws")
jaws: Fish = Fish@2876b359
scala> jaws.name
res4: String = Jaws
scala> jaws.name = "Rex"
<console>:7: error: reassignment to val
jaws.name = "Rex"
^
And private fields?
scala> class Fish(private val name: String) {}
defined class Fish
scala> var jaws = new Fish("Jaws")
jaws: Fish = Fish@15664f1a
scala> jaws.name
<console>:8: error: value name cannot be accessed in Fish
jaws.name
^
scala> jaws.name = "Rex"
<console>:7: error: value name cannot be accessed in Fish
jaws.name = "Rex"
^
What about fields that aren’t in the constructor?
scala> class Fish(val name: String) {
val kind : String = "Shark"
}
defined class Fish
scala> val f = new Fish("Jaws")
f: Fish = Fish@69066caf
scala> f.kind
res12: String = Shark
Well, that’s great , but I want more then one constructor!
scala> class Fish(val name: String) {
def this() = this("SomeName")
}
defined class Fish
scala> var jaws = new Fish()
jaws: Fish = Fish@1dd0eb0b
scala> jaws.name
res6: String = SomeName
And something to tease you – How do you create a private primary constructor?
scala> class Fish private (val name: String) {}
defined class Fish
scala> var jaws = new Fish("Jaws")
<console>:6: error: constructor Animal cannot be accessed in object $iw
var jaws = new Fish("Jaws")
^
Scala has a primary constructor and zero or more auxiliary constructors. The primary constructor is the entire body of the class. So actually , every line written in the body of the class will be executed (not including those inside functions / methods , naturally).
Note: In Scala , any auxiliary constructor must call another constructor of the same class as it’s first actions!
Let’s say we want a fish to print its name when it goes up:
scala> class Fish(var name: String) {
println(“I am “ + name)
}
defined class Fish
scala> var jaws = new Fish("Jaws")
I am Jaws
The code line “println (“I am “ + name)” , although it appears context-less , is actually part of the constructor.
Let’s sum everything up:
class Fish(var name: String, private var age : Int) {
println (“A new fish is born!”);
//This is accessible
val kind : String = "Shark"
//This is not accessible
private val nickName = "Goldi"
def this() = {
//An auxiliary con'r MUST invoke another constructor as it's first action!
this("Fishi", 0)
println ("I'm an auxiliary constructor!")
}
def this(name: String) = this(name, 0);
def swim() = println("Blo Blo")
private def showUpperFin() = println("Dramatic music!")
//If you override a function , you must declare it using the override keyword. Unless the
//function is abstract , and then it's kind of obvious to the compiler
override def toString = "My name is " + name
//An operator is a method just like any other
def + (that: Fish): Fish = return new Fish(this.name,this.age + that.age)
}
So what have we learned so far?
- Scala has a Primary constructor (which is the entire body of the class) and auxiliary constructors – which serve just like Java constructors.
- The default Scala scope is public
- You can declare class parameters in the primary constructor
- You can access and change non private class properties by accessing them directly
The next post will touch the getter/setters issue in Scala , limiting the scope of variables , using default values , and more . Stay tuned
Scala 101 – REPL, Sequences, Tuples, Exceptions
This is part 2 of my Scala tutorial – first part is here All the examples you see here were ran via the REPL – that’s the Scala interpreter. ”>>” denotes the output of the interpreter.
REPL
REPL stands for “wRite, Evaluate, Print, Loop” . It’s basically Scala’s built-in interpreter. To run it , just go to :
[YourScalaDir]\bin\scala.[bat|sh]
Sequences
Sequences in Scala are very easy, and require much less code then Java . It’s more similar to the way Groovy does it (and many other dynamic languages):
Arrays
var a = Array(1,2,3) >> a: Array[Int] = Array(1, 2, 3) var b = Array(1,'a',"Hello") >>b: Array[Any] = Array(1, a, Hello)
What is “Any”? Any is , in a sense , similar to Java’s “Object”. In Java , this line probably wouldn’t have worked , just because in Java , 1 != new Integer(1) – But in Scala , it does – In Scala , everything is an object , including 1 and “Hello”.
use arrays:
a(1) >> Int = 2 a(1)=9 >> Array[Int] = Array(1, 9, 3)
Lists
var l = List(1,2,3) >> l: List[Int] = List(1, 2, 3) var l = List(1,'a',"Hello") >> l: List[Any] = List(1, a, Hello)
First thing you must remember about lists in Scala – They are immutable. So:
l(1) >> Any = a l(1) = 2 >> error: value update is not a member of List[Any] >> l(1)=2
Special sequences functions:
This part will be very familiar for people experienced with ML or Groovy , so I’ll skim about it , but feel free to Google the functions names for me information.
Since Scala is a functional language , it’s very easy to pass a function as a parameter. What does it mean? That if you want to filter an array using a special function ( i>7, for example) – You don’t need to pass an object that knows to run on the type of the array and so forth – it’s as easy as this:
var a = List(2,4,5) var res = a.filter(_ %2 == 0) >> res: List[Int] = List(2, 4)
So what really happened here? We passed a function! If you’re unfamiliar with functional languages , this is quite amazing. you just .. wrote.. a function , with no seemingly function definition , and it just … worked. That’s the magic of functional programming – No wrapping object , no interfaces, no nothing. It’s seems like this is how it always should have been.
A bit more technical discussion :
the _ is a wildcard : it means “The object you’re currently working on” (a bit like $_ in Perl) . What actually goes inside that function can be compared to this Pseudo code:
Array resultArray;
foreach (int i : array) {
if ( i mod 2== 0) { resultArray.add(i)}
}
return resultArray
With the same spirit you can use these popular functions:
- boolean : forall (func : function that returns a boolean) – return true if for each element x , func(x) = true;
- list : filter (func : function that returns a boolean) – return a list with all the elements x for which func(x) = true;
- list : map (func : some function) – return a list with the results of running func(x) on each element x;
Tuples
Tuples are just pure fun. I guess you’ve already bumped into the annoying “A function can return only 1 value” limitation in Java (and C++, and C#, and so forth). So if you want the function to return an int and a String , for example , you’d have to create a whole new Pojo “ResultClass” just to contain those two things. (Yes , you can also use Pair<X,Y> , but what if you want to return 3 values?)
Scala has a very neat solution : tuples . It’s convenient to think about tuples as lists. So you can actually do this:
val pair = (3, "abc") >>pair: (Int, java.lang.String) = (3,abc) pair._1 >> Int = 3
But now for the real treat – Lets make a function that returns 3 elements , and call it :
def f(s : String) = return (s, s.length, s(1))
>> f: (s: String)(String, Int, Char)
var (a, b, c) = f("Hello")
>>a: String = Hello
>>b: Int = 5
>>c: Char = e
You feel that? the freedom? the “Never shall I write a class just to pass 2 parameters again”? – Break the chains
Maps
Maps comes into two flavors : mutable and immutable
- Immutable :
var map = Map(1 -> 'a', 2 -> 'b', 3 ->'c')
- Mutable:
var rwMap = Map[Int, Char]() >> map: scala.collection.immutable.Map[Int,Char] = Map() map += (1 -> 'a') map += (2 -> 'b')
Working with maps:
map(1) >> Char = c
So far so good , but what if the key is not in the map?
map(4) >> java.util.NoSuchElementException: key not found: 4 at scala.collection.MapLike$class.default(MapLike.scala:223) at >>scala.collection.immutable.Map$Map1.default(Map.scala:93) at scala.collection.MapLike$class.apply(MapLike.scala:134) at >>scala.collection.immutable.Map$Map1.apply(Map.scala:93) at .<init>(<console>:7) at .<clinit>(<console>) at RequestResult$.<init> >> (<console>:9) at RequestResult$.<clinit>(<console>) at RequestResult$scala_repl_result(<console>) at >>sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at >>sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at >>sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at >>java.lang.reflect.Method.invoke(Method.java:597) >>at scala.tools.nsc.Interpreter$Reques...
Ouch! What the hell was that?!
Well, Scala acts differently then Java in this case – You don’t get a null , you get an Exception. But that – and I think you’ll all agree with me – is quite nasty.
That’s because there are 2 better ways to access a map in Scala:
The first one is what you would usually implement by yourself in Java:
map.getOrElse(1,'z') >> Char = a map.getOrElse(6,'z') >> Char = z
The other method is fundamentally different:
var res = map.get(1) >> res: Option[Char] = Some(c) res.get >> Char = c
O.K , so what we basically get is an Option for a char – and in this case , it has something , so we got something back. No sweat.
var res = map.get(4) >> Option[Char] = None
But now we have an option for a char – but it contains None – so what will we be getting?
res.get() >> java.util.NoSuchElementException: None.get at scala.None$.get(Option.scala:262) at scala.None$.get(Option.scala:260) at .<init> >>(<console>:8) at .<clinit>(<console>) at RequestResult$.<init>(<console>:9) at RequestResult$.<clinit>(<console>) at >>RequestResult$scala_repl_result(<console>) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at >>sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at >>sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) >>at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:988) at >>scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:9...
Well , that wasn’t very helpful , now wasn’t it? So what are supposed to do with this thing?
The concept of the option is supposed to handle 2 problems :
What “null” means – does it mean that the value of the key was “null” , or that the key is not in the map?
The “Null pointer” exception you might bump into if you didn’t check the returned type.
In this case , you got an object anyway – and you can ask about the content , but you don’t need to check if null before you do. What is usually used is “pattern matching” (we’ll talk more about it in another post) , but for now , it goes something like this: we add capabilities to the “res” param:
res match {
case None => println( "None!")
case Some(x) => println ("Found" + x)
}
>> None!
I know it doesn’t make a lot of sense in this phase , but we’ll get to is soon , I promise – You can learn more about it here, in the mean while
Exceptions
Last thing on the agenda today – Exceptions. Exceptions are handled quite like Java , with one major exception (ha ha) – All exceptions are runtime exceptions. No checked exceptions! So there’s no more need for “throws” , only throw and catch. You can also use finally , same in java
So:
try {
var file = new FileReader("someFile.csv")
} catch {
case ex: FileNotFoundException => println ("Couldn't find it!")
case ex: IOException => println ("Something bad")
} finally {
println ("Finally!" )
}
