Scala Collections I

In this post, Alex Staveley  discusses some of the features that Scala collections offer to developers. Then he compares them with the corresponding Java implementation and gives us a glance in the future with Java 8 Lambda expressions.
Interested to learn more about Scala or Akka? Then visit our Selected Books area
This post contains some info on Scala’s collections.

Problem?

We want a function that will take an List of Rugby players as input and return those players names that play for Leinster and can run the 100 meters from the fastest to the slowest.

Step 1: Have a representation for a Rugby player.

Ok so it’s obvious we want something like a POJO to represent a Rugby player.  This representation should have a player’s name, their team and the time they can the 100 meters in.  Let’s use Scala case class construct which removes the need for boiler plate code.

1
case class RugbyPlayerCaseClass(team: String, sprintTime100M: BigDecimal, name: String)

Step 2: Create some rugby players

1
2
3
4
5
val lukeFitzGerald = RugbyPlayerCaseClass("Leinster", 10.2, "Luke Fitzgerald");
val fergusMcFadden = RugbyPlayerCaseClass("Leinster", 10.1, "Fergus McFadden");
val rog = RugbyPlayerCaseClass("Leinster", 12, "Ronan O'Gara");
val tommyBowe = RugbyPlayerCaseClass("Ulster", 10.3, "Tommy Bowe");
val leoCullen = RugbyPlayerCaseClass("Leinster", 15, "Leo Cullen");

The code above should be self explanatory. The various rugby players are instantiated.  Note the inferred typing. There is no need to declare any of the rugby players as RugbyPlayers types. Instead, it is inferred.  Another thing that is interesting is the keyword val is used.  This means the reference is immutable  It is the equivalent to final in Java.

Step 3: Write the function

1
2
def validByAge(in: List[RugbyPlayerCaseClass]) =
     in.filter(_.team == "Leinster").sortWith(_.sprintTime100M < _.sprintTime100M).map(_.name);
Key points regarding this function:
  • The function begins with def keyword signifying a function declaration.
  • A List of RugbyPlayerCaseClass instances are taken in as input. The List type is a Scala type.
  • The return type is optional. In this case it is not explicitly specified as it is inferred.
  • The part to the left of the = is what the function does. In this case the function invokes three differemt collection operators.
    • .filter(_.team =="Leinster)  - this iterates over every element in the List. In each iteration the _ is filled in with the current value in the List. If the team property of the current Rugby player is Leinster the element is included in the resulting collection.
    • .sortWith(_.sprintTime100M < _.sprintTime100M) - sortWith is a special method which we can use to sort collections. In this case, we our sorting the output from the previous collection operator and we are sorting based on the sprintTime for 100M.
    • .map(_.name) - this maps every element from the output of the sort operator to just their name property.
  • The function body does not need to be surrounded by {} because it is only one line code.
  • There is no return statement needed. In Scala, whatever the last line evaluates to will be returned. In this example since there only is one line, the last line is the first line.

Finally – put it all together.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
object RugbyPlayerCollectionDemos {
  def main(args: Array[String]){
    println("Scala collections stuff!");
    showSomeFilterTricks();
  }
  
  // Case class remove need for boiler plater code.
  case class RugbyPlayerCaseClass(team: String, sprintTime100M: BigDecimal, name: String)
      
  def showSomeFilterTricks() {
  
    // team: String, sprintTime100M: Int, name: String
    val lukeFitzGerald = RugbyPlayerCaseClass("Leinster", 10.2, "Luke Fitzgerald");
    val fergusMcFadden = RugbyPlayerCaseClass("Leinster", 10.1, "Fergus McFadden");
    val rog = RugbyPlayerCaseClass("Munster", 12, "Ronan O'Gara");
    val tommyBowe = RugbyPlayerCaseClass("Ulster", 10.3, "Tommy Bowe");
    val leoCullen = RugbyPlayerCaseClass("Leinster", 15, "Leo Cullen");
    
    println(validByAge(List(lukeFitzGerald, fergusMcFadden, rog, tommyBowe, leoCullen)));
  }
  
  def validByAge(in: List[RugbyPlayerCaseClass]) =
     in.filter(_.team == "Leinster").sortWith(_.sprintTime100M < _.sprintTime100M).map(_.name);
}

The above program will output:

Scala collections stuff!
List(Luke Fitzgerald, Fergus McFadden, Leo Cullen)

Something similar in Java

Pre Java 8, to implement the same functionality in Java would be a lot more code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class RugbyPLayerCollectionDemos {
    public static void main(String args[]) {
     RugbyPLayerCollectionDemos collectionDemos = new RugbyPLayerCollectionDemos();
     collectionDemos.showSomeFilterTricks();
    }
    
    public void showSomeFilterTricks() {
        // team: String, sprintTime100M: Int, name: String
        final RugbyPlayerPOJO lukeFitzGerald = new RugbyPlayerPOJO("Leinster", new BigDecimal(10.2), "Luke Fitzgerald");
        final RugbyPlayerPOJO fergusMcFadden = new RugbyPlayerPOJO("Leinster", new BigDecimal(10.1), "Fergus McFadden");
        final RugbyPlayerPOJO rog = new RugbyPlayerPOJO("Munster", new BigDecimal(12), "Ronan O'Gara");
        final RugbyPlayerPOJO tommyBowe = new RugbyPlayerPOJO("Ulster", new BigDecimal(10.3), "Tommy Bowe");
        final RugbyPlayerPOJO leoCullen = new RugbyPlayerPOJO("Leinster", new BigDecimal(15), "Leo Cullen");
          
        List<rugbyplayerpojo> rugbyPlayers = Arrays.asList(lukeFitzGerald,
          fergusMcFadden, rog, tommyBowe, leoCullen);
        
        System.out.println(filterRugbyPlayers(rugbyPlayers));
    }
    
    
    /**
     * Return the names of Leinster Rugby players in the order of their sprint times.
     */
    public List<string> filterRugbyPlayers(List<rugbyplayerpojo> pojos) {
        ArrayList<rugbyplayerpojo> leinsterRugbyPlayers = new    ArrayList<rugbyplayerpojo>();
     
        for (RugbyPlayerPOJO pojo: pojos) {
            if (pojo.getTeam().equals("Leinster")) {
               leinsterRugbyPlayers.add(pojo);
            }
        }
     
        RugbyPlayerPOJO [] rugbyPlayersAsArray = leinsterRugbyPlayers.toArray(new   RugbyPlayerPOJO[0]);
     
        Arrays.sort(rugbyPlayersAsArray, new Comparator<rugbyplayerpojo>() {
            public int compare(RugbyPlayerPOJO rugbyPlayer1, RugbyPlayerPOJO rugbyPlayer2) {
                 return rugbyPlayer1.getSprintTime100M().compareTo(rugbyPlayer2.getSprintTime100M());
           }
        }); 
     
        List<string> rugbyPlayersNamesToReturn = new ArrayList<string>();
       
        for (RugbyPlayerPOJO rugbyPlayerPOJO: rugbyPlayersAsArray) {
             rugbyPlayersNamesToReturn.add(rugbyPlayerPOJO.getName());
        }
     
        return rugbyPlayersNamesToReturn;
    }
    
    class RugbyPlayerPOJO {
        private BigDecimal sprintTime100M;
        private String team;
        private String name;
     
        public RugbyPlayerPOJO(String team, java.math.BigDecimal sprintTime100M, String name) {
            this.name = name;
            this.sprintTime100M = sprintTime100M;
            this.team = team;
        }
     
        public BigDecimal getSprintTime100M() {
            return sprintTime100M;
        }
     
        public String getTeam() {
            return team;
        }
     
        public String getName() {
            return name;
        }
    }
}
</string></string></rugbyplayerpojo></rugbyplayerpojo></rugbyplayerpojo></rugbyplayerpojo></string></rugbyplayerpojo>

Does Java 8 help out?

Yes. According to the Project Lambda specs Java 8 will have similar looking filter,map and sort functions. The functionality in this post in Java 8 would look something like:

1
2
3
4
5
6
List<rugbyplayerpojo> rugbyPlayers = Arrays.asList(lukeFitzGerald,
  fergusMcFadden, rog, tommyBowe, leoCullen);
//...
//...
List<string> filteredPLayersNames = rugbyPlayers.filter(e -> e.getTeam.equals("Leinster")).
 sorted((a, b) -> a.getSprintTime100M() - b.getSprintTime100M()).mapped(e -> {return e.getName();}).into(new List<>());</string></rugbyplayerpojo>

So Java 8 is definetly catching up a great deal in this regard. But will it be enough?

Re-published article by Alex Staveley.
Original article can be found here :http://dublintech.blogspot.gr/2013/01/scala-collections-1.html
Interested to learn more about Scala or Akka? Then visit our Selected Books area
Tagged with: , ,
Posted in Scala
Pinterest
WP Socializer Aakash Web