I've been building software in Java since 1999. Never has a programming language made such a 180 as the introduction of Streams in Java 8. It changes the way I think about writing software forever. This is why.
- Using Streams teaches you how to do Functional Programming, which is awesome.
- Transforming one object to another is easy
- Less Nullpointer exceptions.
- And lastly and most importantly less (buggy) code.
Below you can see how one would write code which loops through an array of Integers the old/imperative way
Integer[] myIntArray = new Integer[] {1,2,3,4,5,6,7,8,9,10}
for (int i = 0; i < myIntArray.length; i++) {
System.out.println("Looping through " + myIntArray[i]);
}
And this is how it would look when you use Java 8 Streams
Stream.of(1,2,3,4,5,6,7,8,9,10).forEach(i -> {
System.out.println("Looping through " + i);
});
You might say, so what? Well with stream you can manipulate the stream of data way more than I demonstrated.
Stream.of(1,2,3,4,5,6,7,8,9,10).filter(i -> i < 5).forEach(i -> {
System.out.println("Print numbers smaller than 5 here : " + i);
});
Or you can convert an array of one object to an array of another object
Employee maxZilla = Stream.of(
new Person("Max", "Zilla"), //imagine a Person has a first and last name
new Person("Zilla", "Max"),
new Person("John", "Doe"))
.map(person -> new Employee(person, 100000)) //everyone get a salary of 100k
.filter(employee -> "Max".equals(employee.getPerson().firstName)) // only get Max
.findAny() //returns an Optional<Employee> in our case
.orElseThrow(() -> new RuntimeException("no employee found!"))// if none found throw error;
The maxZilla variable here is guaranteed to have either a value or a runtime exception. Imagine writing all that in the imperative way. We didn't create any variables, or mutate anything. This will result in a less buggy code right out of the box.
Handling NullPointers
Remember the days when you have to do this?
public void personMethod(Integer personId) {
Person person = personService.findById(personId); // the bad REST api can return an undocumented null
if (person != null) {
String myName = person.getFirstName();
//do complicated stuff with my name
}else {
throw new PersonNotFoundException("Person with ID "+personId+" not found"); //throw unchecked exception
}
}
in Java 8, you can wrap that in an Optional<T>
public void personMethod(Integer personId) {
Person person = Optional.ofNullable(personService.findById(personId))
.map(Person::getFirstName) //turn to string
.map(firstName -> this.doComplicatedStuff(firstName)) // do complicated stuff with firstName
.orElseThrow(() -> PersonNotFoundException("Person with id " + personId));
}
or sometimes you have to return some default value. You can do this with a one liner in java 8.
This method below will call the service method which returns an Integer. When the service finds the salary, this method will return the salary, or it will return a default 0. No NullPointerExceptions!
public Integer salary(personID) {
return Optional.ofNullable(salaryService.findSalaryFromPersonId(personID)).orElse(0);
}
Anyway I can keep rambling on about how great Java 8 is (all of this is possible with ECMA6 script (java script) too), but new features are abundant in java8, I suggest you have a look at it.
Thanks for reading
Java finally caught up with C# LINQ :)
Yep this style of programming transforms code, cleans up all the imperative noise and makes it far easier to get code working right.
I will be interested to see what other monadic types the Java community build on this.
Good article
Congratulations @maxzilla! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Do not miss the last post from @steemitboard:
Vote for @Steemitboard as a witness to get one more award and increased upvotes!