Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Writing beautiful code with Java 8

481 views

Published on

Java 8 helps use write better looking code. Checked exceptions, however, do not. What can we do to overcome these issues?
Lambdas and streams help us write clear and concise code, but can we do better? Javaslang helps out a bit.
Want more? Maybe turn to Scala.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Writing beautiful code with Java 8

  1. 1. Writing beautiful code with Java 8 sergiu.indrie@iquestgroup.com
  2. 2. Disclaimer This is not a clean code presentation, but rather a code esthetics oriented presentation which may include clean code.
  3. 3. Beautiful code? ● Easy to read/understand/write ● Concise ● DSL-like ● Clean code ++
  4. 4. Ugly vs Beautiful for (int i = 0; i < meetings.size(); i++) { System.out.println(meetings); } for (Meeting meeting : meetings) { System.out.println(meeting); } meetings.forEach(System.out::println);
  5. 5. Ugly vs Beautiful new Thread(new Runnable() { @Override public void run() { System.out.println("Complex stuff"); } }).start(); new Thread(() -> System.out.println("Complex stuff")).start();
  6. 6. Ugly vs Beautiful Map<String, List<Meeting>> meetingsById = meetings.stream() .collect(Collectors.groupingBy(Meeting::getId)); Map<String, List<Meeting>> meetingsGrouped = new HashMap<>(); for (Meeting meeting : meetings) { if (!meetingsGrouped.containsKey(meeting.getId())) { meetingsGrouped.put(meeting.getId(), new ArrayList<>()); } meetingsGrouped.get(meeting.getId()).add(meeting); }
  7. 7. Ugly vs Beautiful // guarded logging if (logger.isDebugEnabled()) { logger.debug("This {} and {} with {} ", 1, that, compute()); } VS logger.debug("This {} ", () -> compute());
  8. 8. What’s “new” in Java 8? ● Lambdas Runnable r2 = () -> System.out.println("Hello world two!"); ● Streams List<Room> rooms = microsoftExchangeService.getRoomLists().getItems().parallelStream() .filter(this::isValidRoomList) .map(this::retrieveRoomsInRoomList) .flatMap(List::stream) .collect(Collectors.toList()); ● Optional Optional<Meeting> meeting = meetingsDao.findById(meetingId); meeting.ifPresent(this::setMeetingAsManuallyEnded);
  9. 9. PS - Help from IDEA ● Migration suggestions (more to come in IDEA 2016.3)
  10. 10. Enemy #1: Checked Exceptions private static void checkedException() { List<String> strings = Arrays.asList(1, 2, 3, 4, 5).stream() .map(Exceptions::intToString) .collect(Collectors.toList()); System.out.println(strings); } private static String intToString(Integer number) throws Exception { if (number == 3) { throw new Exception("wrong number, pal!"); } return String.valueOf(number); }
  11. 11. Enemy #1: Checked Exceptions ● Complex issue (see Brian Goetz’s post from 2010) ○ generic type parameters are monadic ⇒ one exact type ○ throws clauses are variadic ⇒ 0 or more types ● Solution?
  12. 12. Enemy #1: Checked Exceptions - Solution ● 1st Solution - Unchecked Exceptions* ● 2nd Solution - Wrap to 1st (see org.jooq.lambda.Unchecked) public static <T> T unchecked(Callable<T> callable) { try { return callable.call(); } catch (Exception e) { throw new RuntimeException(e); } } List<Room> rooms = roomAddresses.parallelStream() .map(room -> unchecked(() -> getRoomWithoutMeetings(room))) .collect(Collectors.toList()); * Python, Scala, C#, Ruby, PHP … don’t have checked exceptions
  13. 13. Enemy #1: Checked Exceptions - Solution public static <T> T unchecked(Callable<T> callable) { try { return callable.call(); } catch (ApiServiceException e) { throw new ApiServiceRuntimeException(e); } catch (Exception e) { throw runtime(e); } } private static RuntimeException runtime(Throwable e) { if (e instanceof RuntimeException) { return (RuntimeException) e; } return new RuntimeException(e); }
  14. 14. Enemy #1: Checked Exceptions - Solution ● A more functional approach
  15. 15. Enemy #1: Checked Exceptions - Solution ● A more functional approach String complexResult = Try.of(SomeClass::dangerousGet) .recover(x -> Match(x).of( Case(instanceOf(IllegalStateException.class), () -> "1st exception"), Case(instanceOf(IllegalArgumentException.class), () -> "2nd exception") )) .getOrElse("default2");
  16. 16. By the way Java 9 brings: Collection Factory Methods* (all immutable) + some stream improvements like iterate, take/dropWhile * Nevermind if you’ve been using Guava, jOOQ
  17. 17. Java 8 is nice, but don’t // long lambdas numbers.forEach(e -> { int count = 0; for(int i = 1; i <= e; i++) { if(e % i == 0) count++; } System.out.println(count); }); // unformatted streams List<String> strings = Arrays.asList(1, 2, 3).stream().map(Object::toString) .map(String::toUpperCase).limit(5).collect(Collectors.toList());
  18. 18. Java 8 is nice, but Java 8 Computation Style
  19. 19. Level up: Javaslang // Java 8 List<Integer> integers = Arrays.asList(1, 2, 3, 4); List<Integer> evenNumbers = integers.stream() .filter(nr -> nr % 2 == 0) .collect(Collectors.toList()); // Javaslang List<Integer> integers = List.of(1, 2, 3, 4); List<Integer> evenIntegers = integers.filter(nr -> nr % 2 == 0); * javaslang.collection.List
  20. 20. Level up: Javaslang ● “...greatly inspired by Scala” ● Hence very functional ● facilitates functional programming through immutability
  21. 21. List<Integer> integers = Arrays.asList(1, 2, 3, 4); ● List is really javaslang.collection.List :) but we do have toJavaList/Array/Collection/Set() etc. public interface List<T> extends Kind1<List<?>, T>, LinearSeq<T>, Stack<T> { default java.util.List<T> toJavaList() { return ValueModule.toJavaCollection(this, new ArrayList<>()); } ● All Javaslang collections are Iterable and thus can be used in enhanced for-statements for (String s : List.of("Java", "Advent")) { // side effects and mutation } Level up: Javaslang
  22. 22. ● Functional exception handling // no need to handle exceptions Try.of(SomeClass::bunchOfWork).getOrElse("default"); String complexResult = Try.of(SomeClass::dangerousGet) .recover(x -> Match(x).of( Case(instanceOf(IllegalStateException.class), () -> "1st exception"), Case(instanceOf(IllegalArgumentException.class), () -> "2nd exception") )) .getOrElse("default2"); Level up: Javaslang
  23. 23. ● Lazy Lazy<Double> lazy = Lazy.of(Math::random); lazy.isEvaluated(); // = false lazy.get(); // = 0.123 (random generated) lazy.isEvaluated(); // = true lazy.get(); // = 0.123 (memoized) ● + other FP features like function composition, currying, memoization, lifting, immutable collections, tuples Level up: Javaslang
  24. 24. Or maybe just switch to Scala :D // type inference, nice constructors, native streams API, no semicolons :) val integers = List(1, 2, 3, 4) val evenIntegers = integers.filter(_ % 2 == 0) // pre/post/infix operators val sum = (1 to 10).sum // immutable, generated equals/getter/toString/hashcode, pattern matching decomposition case class Person(firstName: String, lastName: String) object Singleton {} // immutable collections, XML processing, multiple inheritance, tuples, REPL etc.
  25. 25. Or maybe just switch to Scala :D // pattern matching & decomposition object Demo { def main(args: Array[String]) { val alice = new Person("Alice", 25) val charlie = new Person("Charlie", 32) for (person <- List(alice, charlie)) { person match { case Person("Alice", 25) => println("Hi Alice!") case Person(name, age) => println( "Age: " + age + " year, name: " + name + "?") } } } case class Person(name: String, age: Int) }
  26. 26. References https://github.com/tedyoung/awesome-java8 https://blog.jooq.org/2014/05/02/java-8-friday-lets-deprecate-those-legacy-libs/ https://blog.jetbrains.com/idea/2016/07/java-8-top-tips/ http://blog.agiledeveloper.com/2015/06/lambdas-are-glue-code.html https://garygregory.wordpress.com/2015/09/16/a-gentle-introduction-to-the-log4j-api-and-lambda-basics/ https://dzone.com/articles/java-8-functional-interfaces-0 http://openjdk.java.net/jeps/269 https://blogs.oracle.com/briangoetz/entry/exception_transparency_in_java http://www.artima.com/intv/handcuffs.html http://www.mindview.net/Etc/Discussions/CheckedExceptions https://github.com/jOOQ/jOOL#orgjooqlambdaunchecked http://iteratrlearning.com/java9/2016/08/06/java9-streams.html http://www.javaslang.io/ http://www.scala-lang.org/
  27. 27. That’s all folks!

×