Code showdown: Java vs Scala - Round 2 - Mathematics
Wednesday, March 9, 2011 10:03:47 PM
For this comparison I used the Problem 3 of Project Euler. The goal is to find the biggest prime factor of 600851475143.
Now there is something I have to say before presenting the code. This time I respected the different paradigms of coding of both Scala and Java. While the Java version is written very imperative and object oriented (is recursion imperative programming?), the Scala version is very functional and implemented as a script executable by the Scala interpreter, although there wouldn't be much overhead (~4 additional lines of code) to make it a full Scala class.
Some might argue that the usage of different coding paradigms renders the whole comparison unusable. But remember that, even though to a certain degree Java can be programmed functional and Scala imperative, this isn't what they where made for.
In Java, the code is as follows:
1 public class PrimeFactors { 2 3 LazyList lazyList = new LazyList(); 4 public static void main(String[] args) { 5 PrimeFactors primeFactors = new PrimeFactors(); 6 System.out.println(primeFactors.getPrimeFactors(600851475143L)); 7 } 8 9 public java.util.Stack<Long> getPrimeFactors(Long target) { 10 java.util.Stack<Long> factors = new java.util.Stack<Long>(); 11 return getPrimeFactors(target, factors); 12 } 13 14 public java.util.Stack<Long> getPrimeFactors(Long target, java.util.Stack<Long> factors) { 15 for(int i=0;;i++) { 16 Long prime = lazyList.get(i); 17 if(prime <= target && target%prime == 0) { 18 factors.push(prime); 19 return getPrimeFactors(target/prime, factors); 20 } 21 else if(prime >= target) { 22 return factors; 23 } 24 } 25 } 26 27 class LazyList { 28 29 private java.util.List<Long> primeNumbers = new java.util.ArrayList<Long>(); 30 31 public LazyList() { 32 primeNumbers.add(2L); 33 } 34 35 public Long get(int i) { 36 if(primeNumbers.size() <= i) { 37 int diff = i - (primeNumbers.size() - 1); 38 for(int x = 0; x < diff; x++) 39 calcNextPrime(); 40 } 41 return primeNumbers.get(i); 42 } 43 44 private void calcNextPrime() { 45 Long start = primeNumbers.get(primeNumbers.size()-1); 46 for(Long counter=start;;counter++) { 47 boolean isPrime = true; 48 for(Long i=2L;i<counter;i++) { 49 if(counter%i == 0) { 50 isPrime = false; 51 break; 52 } 53 } 54 if(isPrime) { 55 primeNumbers.add(counter); 56 break; 57 } 58 } 59 } 60 } 61 }
And now, the equivalent Scala code:
1 val target = 600851475143L 2 val primeList = nextPrime(2L) 3 println(factor(target)) 4 5 def nextPrime(start:Long):Stream[Long] = { 6 isPrime(start) match { 7 case false => nextPrime(start+1L) 8 case true => Stream.cons(start, nextPrime(start+1L)) 9 } 10 } 11 12 def isPrime(num:Long, mod:Long = 2L):Boolean = { 13 num < mod*mod || (num%mod match { 14 case 0 => if(num == mod) true else false 15 case _ => isPrime(num, mod + 1L) 16 }) 17 } 18 19 def factor(num:Long, factors:List[Long] = List()):List[Long] = { 20 println("Get factor for "+num) 21 primeList takeWhile(_ <= num) find(num%_ == 0) match { 22 case None => factors 23 case Some(x) => factor(num/x, x::factors) 24 } 25 }
So this time it's pretty obvious. The Scala code is a lot shorter. Of course, the programming paradigm plays an important role in this. Functional programming just is better suited for mathematical problem solving. Especially the extensive use of pattern matching makes the code a lot shorter and better readable. In Java, on the other hand, recursive functions can cause quite some redundant code by requiring very verbose method overloading. Additionally I had to implement a lazy loading list in Java since there is no equivalent to Scala's "Stream" collection. Regarding this Java stands quite well compared to Scala despite being known as a language that's very verbose.
As for readability, usually a bit more verbose code is more readable. But here, the difference is quite big. Additionally, the Java code uses loops with increment variables, which makes the code less readable.
So this round goes to Scala and functional programming.
Code showdown statistics:
- Readability: Java 0:1 Scala
- length: Java 0:1 Scala
Click the launch button at the end of this post to launch it. (There's some strange layout problem. Just click on "New draggable" to re-layout it.)










