Scala: Collections 1

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.

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

Step 2: Create some rugby players

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

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 declartion.
  • 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 explictly specified as it is inferred.
  • The part to the left of the = is what the function does. In this case the function invokes three difference 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 fromthe 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 ther 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.

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.

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

                       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

                        filterRugbyPlayers(List

                         pojos) {
        ArrayList

                          leinsterRugbyPlayers = new    ArrayList

                          ();

        for (RugbyPlayerPOJO pojo: pojos) {
            if (pojo.getTeam().equals('Leinster')) {
               leinsterRugbyPlayers.add(pojo);
            } 
        }

        RugbyPlayerPOJO [] rugbyPlayersAsArray = leinsterRugbyPlayers.toArray(new   RugbyPlayerPOJO[0]);

        Arrays.sort(rugbyPlayersAsArray, new Comparator

                           () {
            public int compare(RugbyPlayerPOJO rugbyPlayer1, RugbyPlayerPOJO rugbyPlayer2) {
                 return rugbyPlayer1.getSprintTime100M().compareTo(rugbyPlayer2.getSprintTime100M());
           }
        });  

        List

                             rugbyPlayersNamesToReturn = new ArrayList

                             ();

        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;
        }
    }
}

Does Java 8 help out?

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

List

                       rugbyPlayers = Arrays.asList(lukeFitzGerald, 
  fergusMcFadden, rog, tommyBowe, leoCullen);
//...
//...
List

                        filteredPLayersNames = rugbyPlayers.filter(e -> e.getTeam.equals('Leinster')).
 sorted((a, b) -> a.getSprintTime100M() - b.getSprintTime100M()).mapped(e -> {return e.getName();}).into(new List<>());

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

Reference: Scala: Collections 1 from our JCG partner Alex Staveley at the Dublin’s Tech Blog blog.

Related Whitepaper:

Java Essential Training

Author David Gassner explores Java SE (Standard Edition), the language used to build mobile apps for Android devices, enterprise server applications, and more!

The course demonstrates how to install both Java and the Eclipse IDE and dives into the particulars of programming. The course also explains the fundamentals of Java, from creating simple variables, assigning values, and declaring methods to working with strings, arrays, and subclasses; reading and writing to text files; and implementing object oriented programming concepts. Exercise files are included with the course.

Get it Now!  

2 Responses to "Scala: Collections 1"

  1. Haven’t checked, but I believe instead of “sortWith(_.sprintTime100M < _.sprintTime100M)" you can write "sortBy(_.sprintTime100M)". As for Java 8 example, remember that RugbyPlayerPOJO still needs to be declared in its 20+ lines of glory. In Scala case class is much more readable – in one line.

  2. Anon says:

    ‘Ronan O’Gara’ -> ‘Ronan O’Gara’

Leave a Reply


6 − five =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books