Java 8 StringJoiner demo

24 01 2016

Finally Java has convenient and intuitive API for joining strings with delimiters! Since Java 8 there is StringJoiner class. It is an API that you may know from Guava Joiner classes (see my post: https://looksok.wordpress.com/2015/10/17/guava-joiner-join-all-strings-in-an-array-or-map/). Here is a short StringJoiner demo.

Basic String joins

The most basic usage is to create StringJoiner instance with delimiter as a constructor param and add() strings:

StringJoiner joiner = new StringJoiner(",");
joiner.add("apple");
joiner.add("banana");
joiner.add("orange");

System.out.println("Joiner result is: " + joiner.toString());

The result is:

Joiner result is: apple,banana,orange

If you prefer, you can chain add() calls:

StringJoiner joiner = new StringJoiner(",")
    .add("apple")
    .add("banana")
    .add("orange");

Join Collection of Strings

If you have Collection of Strings, the new static String.join() method can join them:

List<String> list = Arrays.asList("apple", "banana", "orange");
String joined = String.join(", ", list);

System.out.println("Join Array result is: " + joined);

With the result of:

Join Array result is: apple, banana, orange

Join inline

You can prepare joined String in one line with String.join() overloaded with varargs, like that:

String.join(", ", "apple", "banana", "orange");

Joining Collector in Stream API

When using streams you have joining Collector at your disposal:

List<String> list = Arrays.asList("apple", "banana", "orange");
String joined = list.stream()
        .collect(Collectors.joining(", "));

System.out.println("Joined with collector: " + joined);

This will result with:

Joined with collector: apple, banana, orange

Source Code

As always, I share with you the source code for this demo on my github: https://github.com/yacekmm/looksok/tree/StringJoinerDemo/Java/JavaDemo





Java 8 Streams demo

28 06 2015

Why streams?

Nearly every Java app iterates collections, making operations on its elements, searching, changing them, sorting and so on. Streams are more readable way of doing this. Streams operations are to some excent similar to SQL Query operations – you can select, filter, order items in collection.

What is a stream

Stream is a sequence of elements. This is simply taken – another abstraction for an array or list.

Follow this post to quickly get the idea behind it. Read Oracle article to learn details.

How to get a stream?

As simple as that:

List<String> list = new ArrayList<String>();
Stream<String> stream = list.stream();

What operations can you do on a stream?

Two types:

intermediate operations: they are called on a Stream type, perform requested operations, and return modified stream. So you can call on it next operation working on Stream (pipelining)

terminal operations that are always placed at the end of a pipeline and return array, list or void. Use them if you want to retrieve a list from a stream for example.

Terminal operation example – printing all list items to the console

Having array list like this:

List<String> names = new ArrayList<String>();
names.add("John");
names.add("Jack");
names.add("Joe");
names.add("Michelle");

And using terminal operation forEach on a Stream you can println() each element from the list.

names.stream()
    .forEach(System.out::println);

The System.out.println is referenced by a static reference with a double colon ‘::‘ – good old C-style operator. So you do not call the println() method immediately but pass its reference to the forEach() and it gets called in its time. This is declarative style of coding – you declare what should be called, not when. JVM calls it for you.

The result on a console is:

John
Jack
Joe
Michelle

Filtering example

filter() operation is an intermediate method that takes a stream, filters it with specified condition and returns filtered stream. Let’s say that I need only names with length > 3:

names.stream()
    .filter(item -> item.length() > 3)
    .forEach(System.out::println);

Here the lambda expression is used. For each item the length check is applied and based on a result the item passes the filter or not. More about Lambda expressions you can read in post Lambda Expression example. The result is:

John
Jack
Michelle

Sorting

To sort items use sorted() intermediate operation and pass a comparing statement to it. I sort names according to the length, descending:

names.stream()
    .filter(item -> item.length() > 3)
    .sorted((item1, item2) -> (item2.length() - item1.length()))
    .forEach(System.out::println);

The lambda expression is comparing two items according to Comparable interface return type: return 0 if equal, and less than zero or more than zero if item2 length is more than item1.

The result is a sorted list:

Michelle
John
Jack

Modify items in stream

map() intermetiade operation allows you to modify each item in a stream. Here, I will greet all of names in the list by concatenating the name with a “Hello” string:

names.stream()
    .filter(item -> item.length() > 3)
    .sorted((item1, item2) -> (item2.length() - item1.length()))
    .map(item -> "Hello, " + item)
    .forEach(System.out::println);

The result is:

Hello, Michelle
Hello, John
Hello, Jack

More pipelining

I can accumulate all the intermediate operations. Here I use one more filter() and map() operations:

names.stream()
    .filter(item -> item.length() > 3)
    .filter((item -> item.startsWith("J")))
    .sorted((item1, item2) -> (item2.length() - item1.length()))
    .map(item -> "Hello, " + item)
    .map(item -> item.toUpperCase() + "!")
    .forEach(System.out::println);

To get the result:

HELLO, JOHN!
HELLO, JACK!

Limit the result size

Let’s say that I need only the first item in a result – I can use limit():

names.stream()
    .filter(item -> item.length() > 3)
    .filter((item -> item.startsWith("J")))
    .sorted((item1, item2) -> (item2.length() - item1.length()))
    .map(item -> "Hello, " + item)
    .map(item -> item.toUpperCase() + "!")
    .limit(1)
    .forEach(System.out::println);

And get the result:

HELLO, JOHN!

Terminal operation: get list from a stream

Now if after all of the operations I need a result as a list again, I can use the terminal operation collect() and pass it the toList() operation:

List<String> result = names.stream()
        .filter(item -> item.length() > 3)
        .filter((item -> item.startsWith("J")))
        .sorted((item1, item2) -> (item2.length() - item1.length()))
        .map(item -> "Hello, " + item)
        .map(item -> item.toUpperCase() + "!")
        .limit(1)
        .collect(toList());
        
System.out.println(result);

I will get the result on a console:

[HELLO, JOHN!]

Get the source code

If you wish to download source code for this guide, go to my github: https://github.com/yacekmm/Java8Streams/tree/String





Java 8 news: Default Interface method example & argumentation

26 04 2014

Java 8 introduces significant changes. One of them are default methods in interfaces.

What has changed
Before Java 8, the interface must not have any method implementation – only the headers.

Since Java 8 the interface can have method implementations. These are called the default methods and does not have to be overriden in implementation classes (but can be). They provide default behaviour for implementations

java8

Example
Here is my basic example of the interface with one default and one normal method:

public interface DefaultMethodInterface {
	
	default void defaultMethod(){
		System.out.println("I'm in a default method!");
	}

	void someOtherMethod();
}

its implementation Overrides only one of the interfaces’ methods. The key is that I do not override the default method (although it is possible). Its implementation remains as defined in interface definition:

public class DefaultlMethodInterfaceImpl implements DefaultMethodInterface{

	@Override
	public void someOtherMethod() {
		System.out.println("This is interface's method implementation.");
	}
}

After using these methods this way:

public static void main(String[] args) {
	DefaultMethodInterface demo = new DefaultlMethodInterfaceImpl();
	demo.someOtherMethod();
	demo.defaultMethod();
}

I get the following output:

This is interface's method implementation.
I'm in a default method!

Both methods are accessible from object implementing the interface.

Why default methods were introduced?
The main reason is to help to maintain backward compatibility with clients that use the interface. Earlier, when the interface definition changed, it required also an implementation change. Now the interface provider, willing to add new method to it can provide the default implementation and allow the clients to work without the need to recompile their implementation.

So what is the difference between Interface and Abstract class now?
Before Java 8, to provide some default behaviour I used the abstract class with few methods implemented, and rest of them declared abstract. Now, when interface can also implement some methods – how does it differ from abstract class?

Does it look like multiple inheritance?
Java does not allow multiple inheritance (the class can extend only one class). The interface default method may somehow break this rule by implementing two interfaces both providing the same default method name. To avoid it, the java compiler will force the class to Override the duplicated method by displaying compile errors. This way it will solve the naming conflicts.

Is it good?
Well… It may be sometimes useful of course, but I would recommend to use it as a tool to provide interface backward compatibility and always consider whether it is not better to extend abstract class instead of implementing an interface with default method. If the problem with multiple inheritance is a blocker consider whether it does not mean some problems with the design. If you still think your design is good – then the default methods may help.

Did I help you?
I manage this blog and share my knowledge for free, sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!





Java 8: new Date API

5 04 2014

Continuing Java 8 goodies, here comes the new Date API! Does it mean that one no longer will need to use Joda Time? Not sure, but surely there is an improvement over Date API in earlier Java versions. Calculating difference between two dates was a nightmare…

Creating new date objects
Date parsing from string in local format or defining new date with variables is more intuitive. This will create new LocalDate object pointing to 5th of February 1987:

LocalDate dateFromString = LocalDate.parse("1987-02-05");
LocalDate dateFromVariables = LocalDate.of(1987, 2, 5);

Adding to and subtracting from dates
To specified LocalDate you can easily add or subtract time units. There are convenient LocalDate instance public methods to do it. Basically to add two weeks to the date, you simply write:

LocalDate weekAfter = dateFromString.plusWeeks(1);

Methods you can use to add or substract:
– plusDays(int), minusDays(int)
– plusWeeks(int), minusWeeks(int)
– plusMonths(int), minusMonths(int)

You can also use generic method plus(int, ChronoUnit) that allows to add number of units to date. For example to add one week with a plus() method you write:

LocalDate weekAfterUnit = dateFromString.plus(1, ChronoUnit.WEEKS);

Calculating difference between two dates
It’s not a nightmare anymore! With a Period class you can calculate how many days, months or years are between two dates. Just use until() method. To calculate difference between today and particular date, do the following:

LocalDate birthDate = LocalDate.parse("1987-02-05");
LocalDate today = LocalDate.now();
Period period = birthDate.until(today);
System.out.println("Years passed: " + period.getYears());

you can also use getMonths() and getDays() methods. To determine whether the date is before or after another date, use the isNegative() method on a Period object.

Did I help you?
I manage this blog and share my knowledge for free, sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!





Java 8: Lambda expression example

29 03 2014

Lambda expression are a short-form replacement for anonymous classes. They help in cases where you have to declare an interface with a single abstract method (such an interface is called functional interface) and its implementation.

lambda

In short words
The function is now an Object since Java 8. It is now the first-class citizen, like primitives and other Objects. What does it mean? Now you can pass a function as an another method’s parameter. This is inspired by functional languages like Scala or JavaScript.

Before Java 8, to emulate method passing as a parameter, you had to use a dedicated object. Now, you can pass the method without packing it into object, using the notion of anonymous class definition.

Note: To compile Java 8 code, you need JDK 8 installed, and JRE, like Eclipse (Kepler with this plugin or Luna that in theory does not require any additional plugins. In reality. I also had to install the plugin  in Luna to make it compile with Java 8).

The syntax
Syntax is not obvious or self explanatory in my opinion, however I am sure I will get used to it. Basically to define the behaviour you use:

(formal parameter list comma separated) -> { expression or statements }

where parameters are related to your interface method declaration and the expression is just anonymous method body, where these parameters are processed.

The source code is here!
Feel free to download my sample eclipse Lambda demo project from here.

Example
Let’s assume that we have a list of persons and print method that prints its items that satisfy condition. The condition is: Print only those, whose phone number begins with “+48”. We iterate over each item in list and call print method, that takes two parameters:
– the list item
– the function testing for defined condition

void printPerson(PersonInfo personInfo, PrintCondition condition)

Define functional interface
The PrintCondition is a functional interface with one method declaration:

public interface PrintCondition {
	public boolean isSatisfied(PersonInfo personInfo);
}

Method’s parameter list consists of one object: PersonInfo, and returns boolean indicating whether the condition is satisfied. We’re still in good old Java way of doing it.

The print method
Print method takes PersonInfo object and PrintCondition. If condition is satisfied, it prints the PersonInfo, otherwise does nothing:

private static void printPerson(PersonInfo personInfo, PrintCondition condition){
	if(condition.isSatisfied(personInfo))
		System.out.println(personInfo);
}

Here comes the Lambda!
I have a method that iterates over all list items and prints each, depending on condition. In my foreach loop I call the printPerson method with Lambda inside:

for (PersonInfo personInfo : persons) {
	printPerson(
			personInfo, 
			//Here goes the lambda expression param:
			(PersonInfo person) -> {
				return person.getPhoneNumber().startsWith("+48");
			});
			//that's it!
}

Basically speaking, this is the implementation of the PrintCondition’s interface method that is passed to printPerson body. I pass the PersonInfo param and get returned the boolean.

How would it look like without Lambda?
The same loop before Java 8 would be defined with an anonymous inner class implementing the PrintCondition interface, as follows:

for (PersonInfo personInfo : persons) {
	printPerson(
		personInfo, 
		//Here we go without lambda!
		new PrintCondition() {
			@Override
			public boolean isSatisfied(PersonInfo person) {
				return person.getPhoneNumber().startsWith("+48");
			}
		}
	);
}

Reduce Lambda expression verbosity even more
There are some things to be reduced in my Lambda expression:
– you don’t need the curly braces around Lambda expression, if you have just one line of code
– you don’t need the return keyword. The statement’s return value will be returned automatically, if you have just one line of code
– you don’t need the semicolon at its end, if you have just one line of code
– you don’t have to pass parameter name, just its type

After applying clues above, the expression is now like that:

//Here goes even shorter lambda expression:
(PersonInfo) -> 
	personInfo.getPhoneNumber().startsWith("+48")

The shortest Lambda you can write
If you want your test condition to always evaluate to true (return true), the lambda expression would look like this:

(PersonInfo) -> true

But then why would you need the PersonInfo in this statement? If you refactor your interface method not to take any arguments like this:

public boolean isSatisfied();

The lambda would not need the PersonInfo param. Guess how it would look like? Well… exactly like that:

() -> true

Using built-in Java functional interfaces: Predicate
Here I used my own functional interface to provide test method. Such test is so widely used that such interface is a part of Java language under java.util.function.Predicate. It can get an object to test via generic argument and call your test method.

With the Predicate you don’t need the PrintCondition Interface at all. The lambda expression remains unchanged, the only change is in a print method declaration and body to get the Predicate param instead of PrintCondition, and then to call test() instead of PrintCondition’s isSatisfied():

private static void printPerson(PersonInfo personInfo, Predicate<PersonInfo> predicate){
	if(predicate.test(personInfo))
		System.out.println(personInfo);
}

The source code is here!
Feel free to download my sample eclipse Lambda demo project from here.

Other resources

Here are the other resources that can help you understand Lambdas:

– http://www.oracle.com/technetwork/articles/java/lambda-1984522.html

– http://viralpatel.net/blogs/lambda-expressions-java-tutorial/

 

Did I help you?
I manage this blog and share my knowledge for free, sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!








%d bloggers like this: