Let's improve stacker's example and use Scala's case classes.
Let's improve stacker's example and use Scala's case classes: case class Person(firstName: String, lastName: String) The above Scala class contains all features of the below Java class, and some more - for example it supports pattern matching (which Java doesn't have). Scala 2.8 adds named and default arguments, which are used to generate a copy method for case classes, which gives the same ability as the with* methods of the following Java class. Public class Person implements Serializable { private final String firstName; private final String lastName; public Person(String firstName, String lastName) { this.
FirstName = firstName; this. LastName = lastName; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public Person withFirstName(String firstName) { return new Person(firstName, lastName); } public Person withLastName(String lastName) { return new Person(firstName, lastName); } public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass()! = o.getClass()) { return false; } Person person = (Person) o; if (firstName!
= null?!firstName. Equals(person. FirstName) : person.
FirstName! = null) { return false; } if (lastName! = null?!lastName.
Equals(person. LastName) : person. LastName!
= null) { return false; } return true; } public int hashCode() { int result = firstName! = null? FirstName.hashCode() : 0; result = 31 * result + (lastName!
= null?LastName.hashCode() : 0); return result; } public String toString() { return "Person(" + firstName + "," + lastName + ")"; } } Then, in usage we have (of course): Person mr = new Person("Bob", "Dobbelina"); Person miss = new Person("Roberta", "MacSweeney"); Person mrs = miss. WithLastName(mr.getLastName()); Against val mr = Person("Bob", "Dobbelina") val miss = Person("Roberta", "MacSweeney") val mrs = miss copy (lastName = mr.lastName).
You have to be careful though - case classes inherit from Product and hence primitives will be boxed (in scala 2.7) or probably-boxed (2.8 using specialization) – oxbow_lakes Jun 3 '10 at 10:38 In 2.7. X and 2.8.0 the only boxing is in productElements and unapply, not in the constructor, field, or accessor: gist.github.com/424375 – retronym Jun 3 '10 at 19:58 1 Encourages all sorts of getter/setter badness. Setters should only be added with extreme reluctance, getters should be only added if necessary. Good example of how adding "Simplicity" leads to bad habits.
– Bill K Jul 2 '10 at 21:37 2 @Bill K: OK, then we will have case class Person(val firstName: String, val lastName: String) So what? Making that thing private would be possible too, but doesn't make any sense, because of unapply etc.– soc Jul 16 '10 at 19:49.
I found this one impressive Java public class Person { private final String firstName; private final String lastName; public Person(String firstName, String lastName) { this. FirstName = firstName; this. LastName = lastName; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } } Scala class Person(val firstName: String, val lastName: String) As well as these ones (sorry for not pasting, I didn't want to steal the code) Queens-Problem Java Queens-Problem Scala.
1. Very nice one! – Roman Jun 1 '10 at 19:44 This scala code will not generate getFirstName and getLastName methods.
You have to annotate the parameters with scala.reflect. BeanProperty annotation to do that. – Abhinav Sarkar Jun 1 '10 at 20:01 5 @abhin4v: Yes, but the code convention in Scala is to not have accessors prefixed with get.
Idiomatic Java code is different from idiomatic Scala code. Sometimes the is prefix used for booleans. Davetron5000.github.com/scala-style/naming_conventions/methods/… – Esko Luontola Jun 1 '10 at 20:40 3 You could make that a case class and get the toString, equals and hashCode for free (and you also don't have to make the arguments val explicitly): case class Person(firstName: String, lastName: String) – Jesper Jun 1 '10 at 20:50.
Task: Write a program to index a list of keywords (like books). Explanation: Input: List Output: Map The key of map is 'A' to 'Z' Each list in the map are sorted. Java: import java.util.
*; class Main { public static void main(String args) { List keywords = Arrays. AsList("Apple", "Ananas", "Mango", "Banana", "Beer"); Map result = new HashMap(); for(String k : keywords) { char firstChar = k. CharAt(0); if(!result.
ContainsKey(firstChar)) { result. Put(firstChar, new ArrayList()); } result. Get(firstChar).
Add(k); } for(List list : result.values()) { Collections. Sort(list); } System.out. Println(result); } } Scala: object Main { def main(args: ArrayString) { val keywords = List("Apple", "Ananas", "Mango", "Banana", "Beer") val result = keywords.
GroupBy(_(0)). MapValues(_. Sorted) println(result) } }.
You can use v. Sorted instead of (v sortBy identity). – Eastsun Jun 2 '10 at 4:14 @Eastsun, Thanks, edited.
– missingfaktor Jun 2 '10 at 5:38 1 And with Scala 2.8, you can use mapValues (_. Sorted) instead of map { case ... } – Alex Boisvert Jun 2 '10 at 16:01.
Task: You have got an XML file "company. Xml" that looks like this: Tom Cruise Paul Enderson George Bush You have to read this file and print the firstName and lastName fields of all the employees. Java: taken from here import java.io.
File; import javax.xml.parsers. DocumentBuilder; import javax.xml.parsers. DocumentBuilderFactory; import org.
W3c.dom. Document; import org. W3c.dom.
Element; import org. W3c.dom. Node; import org.
W3c.dom. NodeList; public class XmlReader { public static void main(String args) { try { File file = new File("company. Xml"); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.
NewDocumentBuilder(); Document doc = db. Parse(file); doc. GetDocumentElement().normalize(); NodeList nodeLst = doc.
GetElementsByTagName("employee"); for (int s = 0; s { for(e I guess I'll edit your answer and let you delete it if it bugs you. This is how I would do it in Java with better libraries: public scanForEmployees(String filename) { GoodXMLLib source=new GoodXMLLib(filename); while( String employee: source. ScanFor("employee", "firstname", "lastname") ) { System.out.
Println("First Name: " + employee0); System.out. Println("Last Name: " + employee1); } } This is just a quick hack involving no magic and all reusable components. If I wanted to add some magic I could do something better than returning an array of string arrays, but even as is this GoodXMLLib would be completely reusable.
The first parameter of scanFor is the section, all future parameters would be the items to find which is limited, but the interface could be buffed slightly to add multiple levels of matching with no real problem. I will admit that Java has some pretty poor library support in general, but come on--to compare a horrible usage of Java's decade(?) old XML library to an implementation done based on being terse is just not fair--and is far from a comparison of the languages!
Hmm, the Java example would be shorter and better looking with a SAX or StAX parser. But still the SCALA one is really nice – oluies Jun 4 '10 at 18:52 The Java code is written exactly to parse that particular XML file with no attempt at reuse and a lot of duplicated code. Whoever wrote it was either trying to deliberately look like he didn't understand coding or didn't understand coding.
– Bill K Jul 2 '10 at 21:42 @Bill K: I have never done XML parsing in Java so I picked this example from some random site. Feel free to edit the Java part of the answer, I don't mind. – missingfaktor Jul 3 '10 at 4:33 Well, let's assume that you are talking language differences and not library differences--in that case, the two would be nearly identical.
The only language difference in the second example is the match/case thing which could be done in a single line as a for loop if implemented that way by the library. – Bill K Jul 6 '10 at 16:07 @Bill K: No, you are completely wrong. There are two very powerful Scala features at work here: 1.
XML Literals 2. Pattern Matching. Java doesn't have either of these.So the equivalent Java code written in some hypothetical library will sure NOT be identical.
(Try writing, you'll know. ) – missingfaktor Jul 6 '10 at 19:10.
I liked user unknown's answer so much I'm going to try to improve upon it. The code below is not a direct translation of the Java example, but it accomplishes the same task with the same API. Def wordCount (sc: Scanner, delimiter: String) = { val it = new IteratorString { def next = sc.nextLine() def hasNext = sc.hasNextLine() } val words = it flatMap (_ split delimiter iterator) words.
ToTraversable groupBy identity mapValues (_. Size) }.
I don't have scala-2.8 installed by now, to test this snippet, but I guess I can see what is intendet - just 'keywords' aren't used at all. It produces a map of all Strings and their frequencies, doesn't it? – user unknown Jun 7 '10 at 17:52 @user Yes, that's what it does.
Isn't that what's accomplished by your code? Oh, I see. I copied the wrong line.
I'm gonna fix it right now. :-) – Daniel C. Sobral Jun 7 '10 at 23:30.
A map of actions to perform depending on a string. Java: // strategy pattern = syntactic cruft resulting from lack of closures public interface Todo { public void perform(); } final Map todos = new HashMap(); todos. Put("hi", new Todo() { public void perform() { System.out.
Println("Good morning! "); } } ); final Todo todo = todos. Get("hi"); if (todo!
= null) todo.perform(); else System.out. Println("task not found") Scala: val todos = Map( "hi" -> { () => println("Good morning! ") } ) val defaultFun = {() => println("task not found")}; todos.
GetOrElse("hi", defaultFun).apply() And it's all done in the best possible taste!
Rahul G, I think your edit is incorrect. Todos. Get("hi") returns Option()=>Unit which is needed to match properly.
– huynhjl Jun 3 '10 at 13:53 @huynhjl, My bad. Rolled it back. – missingfaktor Jun 3 '10 at 14:56 1 Can be even shorter: val defaultFun = {() => println("task not found")}; todos.
GetOrElse("hi", defaultFun).apply() – Geoff Reedy Jun 9 '10 at 21:18 awesome, thanks Geoff. Adding your suggestion. – Ben Hardy Jul 2 '10 at 21:33.
The Circuit Breaker pattern from Michael Nygard's Release It in FaKods (link to code) implementation looks like this in Scala: . . .
AddCircuitBreaker("test", CircuitBreakerConfiguration(100,10)) . . .
Class Test extends UsingCircuitBreaker { def myMethodWorkingFine = { withCircuitBreaker("test") { . . .
} } def myMethodDoingWrong = { withCircuitBreaker("test") { require(false,"FUBAR! ") } } } Which I think is super nice. It looks just as a pice of the language but it is a simple mixin in the CircuitBreaker Object doing all work.
/** * Basic MixIn for using CircuitBreaker Scope method * * @author Christopher Schmidt */ trait UsingCircuitBreaker { def withCircuitBreakerT(name: String)(f: => T): T = { CircuitBreaker(name). Invoke(f) } } Reference in other languages Google for "Circuit breaker" + your language.
I like much the method getOrElseUpdate, found in mutableMap and shown here, first Java, without: public static Map wordCount (Scanner sc, String delimiters) { Map dict = new HashMap (); while (sc. HasNextLine ()) { String words = sc. NextLine ().
Split (delimiters); for (String word: words) { if (dict. ContainsKey (word)) { int count = dict. Get (word); dict.
Put (word, count + 1); } else dict. Put (word, 1); } } return dict; } yes - a WordCount, and here in scala: def wordCount (sc: Scanner, delimiter: String) = { val dict = new scala.collection.mutable. HashMap String, Int() while (sc.
HasNextLine ()) { val words = sc.nextLine. Split (delimiter) words. Foreach (word => dict.
Update (word, dict. GetOrElseUpdate (word, 0) + 1)) } dict } filter and sort have already been shown, but look how easy they are integrated with the map: def filterKeywords (sc: Scanner, keywords: ListString) = { val dict = wordCount (sc, "^A-Za-z") dict. Filter (e => keywords.
Contains (e. _1)). ToList .
Sort (_. _2.
I like this example a lot. It avoids the easy route of comparing case classes, and doesn't make the mistake of showing Scala code and not the Java equivalent. – Daniel C.
Sobral Jun 7 '10 at 4:03.
Task: You have a list people of objects of class Person that has fields name and age. Your task is to sort this list first by name, and then by age. Java: Collections.
Sort(people, new Comparator() { public int compare(Person a, Person b) { return a.getName(). Compare(b.getName()); } }); Collections. Sort(people, new Comparator() { public int compare(Person a, Person b) { return Integer.
ValueOf(a.getAge()). Compare(b.getAge()); } }); Scala: val sortedPeople = people. SortBy(p => (p.
Name, p. Age)).
Missing lambdas (or at least method references) is most important feature I miss in Java. – Petr Gladkikh Feb 1 '11 at 7:15.
This is a very simple example: Square integers and then add them public int sumSquare(int list) { int s = 0; for(int I = 0; I x * x ). FoldLeft(0)((s,i) => s + I ) This one I will not try in Java (to much work), turn XML to a Map: Scala rules Another one liner to get the map from the XML: val xml = Scalarules val map = xml.child. Map( n => (n \ "@id").
Text -> n.child. Text). ToMap // Just to dump it.
For( (k,v) " + v).
The problem with your sumSquare in Scala is that it looks very cryptic to a Java developer, which will give them ammo against you to complain that Scala is obscure and complicated... – Jesper Jun 1 '10 at 20:53 I reformatted a bit to improved the example. Hope that this does not hurt Scala. – Thomas Jun 1 '10 at 21:14 3 scala> 1 to 10 map (x => x*x) sum res0: Int = 385 Let's see the java developer call that cryptic.At that point it's fingers in the ears saying nah-nah-nah.
– extempore Jun 2 '10 at 3:30 1 @Jesper To a non-Java developer, Java looks like vast amounts of boilerplate and line noise. That doesn't mean you can't get real work done in the language. – James Moore Jun 2 '10 at 13:18 You could use reduceLeft(add) instead of foldLeft(0)(add).
I think it’s easier to read when your start element is the group’s zero/identity element. – Debilski Jun 2 '10 at 16:03.
Java The following is a java example found via a google search, the URL is mycstutorials.com/articles/sorting/quick... public void quickSort(int array) // pre: array is full, all elements are non-null integers // post: the array is sorted in ascending order { quickSort(array, 0, array. Length - 1); // quicksort all the elements in the array } public void quickSort(int array, int start, int end) { int I = start; // index of left-to-right scan int k = end; // index of right-to-left scan if (end - start >= 1) // check that there are at least two elements to sort { int pivot = arraystart; // set the pivot as the first element in the partition while (k > i) // while the scan indices from left and right have not met, { while (arrayi i) // from the left, look for the first i++; // element greater than the pivot while (arrayk > pivot && k >= start && k >= i) // from the right, look for the first k--; // element not greater than the pivot if (k > i) // if the left seekindex is still smaller than swap(array, i, k); // the right index, swap the corresponding elements } swap(array, start, k); // after the indices have crossed, swap the last element in // the left partition with the pivot quickSort(array, start, k - 1); // quicksort the left partition quickSort(array, k + 1, end); // quicksort the right partition } else // if there is only one element in the partition, do not do any sorting { return; // the array is sorted, so exit } } public void swap(int array, int index1, int index2) // pre: array is full and index1, index2 Nil case pivot::tail => qsort(tail. Filter(_ = pivot)) } }.
Usually mergesort or similar is used for linked lists. – Esko Luontola Jun 2 '10 at 5:53 3 It's also not tail recursive and hence unsuitable as a performant algorithm (or one which will not overflow the stack) – oxbow_lakes Jun 2 '10 at 11:01 Thanks for the useful comments. I had seen quicksort written like this somewhere and was impressed by it's compactness, clearly I didn't give it much consideration.
I got carried away by the LOC comparison, which is always a seductive thing with Scala v Java. – Don Mackenzie Jun 2 '10 at 21:47 Quicksort is not O(n^2) on functional lists, but it certainly has that danger. Asymptotically, it's still average O(n log n), but there is a higher statistical probability of hitting the worst case O(n^2) because we always select the pivot point at the head of the list, rather than choosing one at random.
– Daniel Spiewak Jun 2 '10 at 1:36 Filtering twice is bad. See in my answer to your question the use of partition to avoid that. – Daniel C.
Sobral Jun 2 '10 at 3:52.
I liked this simple example of sorting and transformation, taken from David Pollak's 'Beginning Scala' book: In Scala: def validByAge(in: ListPerson) = in. Filter(_. Valid).
SortWith(_. Age 18} validByAge(List(Person("John", "Valid", 32), Person("John", "Invalid", 17), Person("OtherJohn", "Valid", 19))) In Java: public static List validByAge(List in) { List valid = new ArrayList(); for (Person p: in) { if (p.valid()) valid. Add(p); } Collections.
Sort(people, new Comparator() { public int compare(Person a, Person b) { return a.age() - b.age(); } } ); List ret = new ArrayList(); for (Person p: people) { ret. Add(p. First); } return ret; } public class Person { private final String firstName; private final String lastName; private final Integer age; public Person(String firstName, String lastName, Integer age) { this.
FirstName = firstName; this. LastName = lastName; this. Age = age; } public String getFirst() { return firstName; } public String getLast() { return lastName; } public Integer getAge() { return age; } public Boolean valid() { return age > 18; } } List input = new ArrayList(); input.
Add(new Person("John", "Valid", 32)); input. Add(new Person("John", "InValid", 17)); input. Add(new Person("OtherJohn", "Valid", 19)); List output = validByAge(input).
Problem: you need to design a method that will execute any given code asynchronously. Solution in Java: /** * This method fires runnables asynchronously */ void execAsync(Runnable runnable){ Executor executor = new Executor() { public void execute(Runnable r) { new Thread(r).start(); } }; executor. Execute(runnable); } ... execAsync(new Runnable() { public void run() { ... // put here the code, that need to be executed asynchronously } }); The same thing in Scala (using actors): def execAsync(body: => Unit): Unit = { case object ExecAsync actor { start; this!
ExecAsync loop { react { case ExecAsync => body; stop } } } } ... execAsync{ // expressive syntax - don't need to create anonymous classes ... // put here the code, that need to be executed asynchronously }.
3 As of 2.8, this can be written as Futures. Future{body} and is actually more powerful since the future returned by this can be joined to get the value it eventually evaluates to. – Dave Griffith Jun 23 '10 at 0:41.
This Scala code... def partitionT(items: ListT, p: (T, T) => Boolean): ListListT = { items. FoldRightListListT(Nil)((item: T, items: ListListT) => items match { case (first :: rest) :: last if p (first, item) => (List(item)) :: (first :: rest) :: last case (first :: rest) :: last => (item :: first :: rest) :: last case _ => List(List(item)) }) } ...would be completely unreadable in Java, if possible at all.
5 MY correct OPINIO: thanks for the answer! But could you please explain what happens there? I'm not familiar with Scala syntax yet, and (that's the possible reason why) it looks completely unreadable even now for me.
– Roman Jun 2 '10 at 14:26 It's partitioning a generic list of type T using a provided partitioning function as a guard in the pattern matching clauses of the case statement. – JUST MY correct OPINION Jun 2 '10 at 14:35 1 Weird. I'm not even remotely a Scala expert and can figure that out.
– JUST MY correct OPINION Jun 2 '10 at 17:07.
Why nobody posted this before: Java class { public static void main( String args ) { System.out. Println(" } } 118 characters. Scala object extends Application { println(" world") } 66 characters.
Application trait considered harmful... scala-blogs.org/2008/07/… – missingfaktor Jun 3 '10 at 6:06.
Lazily evaluated infinite streams are a good example: object Main extends Application { def from(n: Int): StreamInt = Stream. Cons(n, from(n + 1)) def sieve(s: StreamInt): StreamInt = Stream. Cons(s.
Head, sieve(s. Tail filter { _ % s. Head!
= 0 })) def primes = sieve(from(2)) primes take 10 print } Here is a question addressing infinite streams in Java: Is an infinite iterator bad design? Another good example are first class functions and closures: scala> def f1(w:Double) = (d:Double) => math. Sin(d) * w f1: (w: Double)(Double) => Double scala> def f2(w:Double, q:Double) = (d:Double) => d * q * w f2: (w: Double,q: Double)(Double) => Double scala> val l = List(f1(3.0), f2(4.0, 0.5)) l: List(Double) => Double = List(, ) scala> l.
Map(_(2)) res0: ListDouble = List(2.727892280477045, 4.0) Java doesn't support first class functions, and mimicking closures with anonymous inner classes isn't very elegant. Another thing this example shows that java can't do is running code from an interpreter/REPL. I find this immensely useful for quickly testing code snippets.
Please note that the sieve is too slow to be practical. – Elazar Leibovich Jun 2 '10 at 4:12 Where is the Java? – oxbow_lakes Jun 3 '10 at 10:40 @oxbow_lakes there is no equivalent java for these examples.
– dbyrne Jun 3 '10 at 12:51 @dbyme Not true. You can easily subclass Java's Iterable and Iterator to produce infinite streams. – Daniel C.
Sobral Jun 9 '10 at 15:52 @Daniel I stand corrected. Answer has been updated. – dbyrne Jun 9 '10 at 21:01.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.