Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

By hand

Back in the olden days, if you needed a CSV, you would create it by iterating over your data, appending to a String with your separator, then lopping off the last character. Something like this:

StringBuilder messages = new StringBuilder();   
for (String message : kycModel.getMessages()) { 
    messages.append(message).append(",");       
}                                               
myObject.setValue(messages.toString());                        

Apache

Along came Apache Commons and we started using StringUtils.join.

myObject.setValue(StringUtils.join(messages, ","));

Java 8 StringJoiner

Java 8 brought the StringJoiner. The StringJoiner constructor comes in 2 flavors.
new StringJoiner(delimiter)

  • delimeter – the value that will be used to separate the items. The “,” is used for a CSV.

new StringJoiner(delimeter, prefix, suffix)

  • delimeter – The delimeter is the same as the regular constructor.
  • prefix – a character(s) that will be put at the beginning of the sequence (e.g. “[“).
  • suffix – the character(s) that will be placed at the end of the sequence (e.g. “]”).

An example of using the StringJoiner:

StringJoiner stringJoiner = new StringJoiner(",");  
for (String message : kycModel.getMessages()) {     
    stringJoiner.add(message);                      
}                                                   
myObject.setValue(stringJoiner.toString());         

That can be made much easier by using the Java 8 forEach:

StringJoiner stringJoiner = new StringJoiner(",");
kycModel.getMessages().forEach(stringJoiner::add);
myObject.setValue(stringJoiner.toString());

If you really want to squeeze it down further, you can also take advantage of the Java 8 stream

myObject.setValue(kycModel.getMessages().stream().map(String::toString).collect(Collectors.joining(",")));  

September 15th, 2015

Posted In: Java, java ninja, Javaninja, Stream

Tags: , , , , ,

Leave a Comment

Streams, functional programming and Lambda expressions have opened up a whole new world of syntax for the Java language. The old forEach has new competition.

An example of a normal forEach of a list of objects was:

for (MyModel myModel : myModelList) {
    System.out.println(myModel);
}

This can be replaced with .forEach and the code gets much smaller.

myModelList.forEach(System.out::println);

One common thing to do with a forEach is to iterate over a set of data and pick and choose which objects should be added to another list.
An example of a forEach that filters a list is:

List<GameModel> externalGames = new LinkedList<>();
for (GameModel myModel : gameList) {
    if ("external".equals(myModel.getIdGameExternal())) {
        externalGames.add(myModel);
    }
}

This is when it gets fun. We can use .filter and .collect to transform this into the following. The .filter contains all of the logic that you would have had in an if statement. The .collect contains the processing necessary to convert the stream to a LinkedList.

externalGames = gameList.stream()
                        .filter(myModel -> "external".equals(myModel.getIdGameExternal()))
                        .collect(Collectors.toCollection(LinkedList::new));

Sometimes you need just one element from a list. Here is what a typical forEach loop looks like that filters a list down and then we get a reference to the first object in the list.

List<GameModel> externalGames = new LinkedList<>();
for (GameModel myModel : gameList) {
    if ("external".equals(myModel.getIdGameExternal())) {
        externalGames.add(myModel);
    }
}
gameModel1 = externalGames.get(0);

We can easily do the same thing using streams. In this case, I filter like before, then grab the first element. We pull out .findFirst to retrieve the first element of the stream, then use .get to make that object available.

gameModel1 = gameList.stream()
                     .filter(myModel -> "external".equals(myModel.getIdGameExternal()))
                     .findFirst()
                     .get();

Sometimes you have the case where you want to search through a collection of data and if an element contains a specific value, set something else. In this case, we use findFirst() and isPresent() to set a boolean value based upon an element in the collection having a specific value.

inBonus = bonusRedemptionModel.getBonusTransactions()
                              .stream()
                              .filter(b -> BonusOperationEnum.OPT_OUT.value().equals(b.getIdOperation()))
                              .findFirst()
                              .isPresent();

August 6th, 2015

Posted In: Collections, Java, java ninja, Javaninja

Tags: , , , , ,

Leave a Comment

WP to LinkedIn Auto Publish Powered By : XYZScripts.com