📜 ⬆️ ⬇️

Love and hate java 8

It seems Java 8 is the most awaited release of all time . The initial planning release for September last year was postponed to March of the next year, presumably to spend more time on security improvements , mainly aimed at the client side of Java (JavaFX / Swing).

The new version of Java is trying to "improve" as understood by the word Microsoft . This means stealing much of the things that other frameworks and languages ​​have taken care of, then incorporating them into a language or runtime. In anticipation of a new release, the Java community is discussing Project Lambda, stream, functional interfaces and other buns. So let's consider what is good and what we can hate.

Stream


The main innovation is the collection, called Stream, not to be confused with the InputStream and OutputStream. Stream does not replace ArrayLists or other collections. This innovation makes managing data faster and easier. Stream is a one-time object, i.e. You can process the data in it once.

Stream has the ability to use the filter, map, reduce functions to process it. For Stream there are two modes: serial and parallel. This allows the use of multi-core processors. Collections use fork / join parallelism to break work into parts.
')
For serial mode:
List <Person> people = list.getStream.collect(Collectors.toList()); 


For parallel mode:
 List <Person> people = list.getStream.parallel().collect(Collectors.toList()); 


During sequential Stream processing, each element is processed in turn. And in parallel mode, the array is divided into parts, each of which is processed in a separate stream. Then the results of processing are collected in the overall result.

Processing in parallel mode looks like this:
 List originalList = someData; split1 = originalList(0, mid); split2 = originalList(mid,end); new Runnable(split1.process()); new Runnable(split2.process()); List revisedList = split1 + split2; 


Stream can be processed only once, and it returns another Stream, so you can use the final (terminal) function to get a useful result. For example, the functions sum (), collect (), toArray (). As long as the final function is not applied to the Stream, the processing result is not calculated. For example:

 Double result = list.getStream().mapToDouble(f -> f.getAmount()).sum(); List<Person> people = list.getStream().filter(f -> f.getAge() > 21).collect(Collectors.toList()); 


The big benefit of this is the ability to use multiple processor cores to handle the collection. Instead of using the traditional for-loop, using Stream in parallel mode is theoretically accelerated, with an increase in the number of cores involved in processing. The main possible problem is the loss of readability of the code with a large number of operations performed on the collection. Other problems arise from the addition of support for new features — functional interfaces and lambdas.

Functional Interfaces


In general, it’s just adding default-methods to the interface with the possibility of calling them directly from the interface. Also, it is not necessary to override them in the implementation of the interface.

This was done for backward compatibility with your collections in your interfaces. Those. Solving the problem of placing a Stream into an interface without having to change all the classes that implement this interface. Therefore, creating a default method in an interface allows all classes implementing the interface to use threads. If the default method is not correct, then it may be overloaded.

Essentially, default methods are a form of multiple inheritance. And it becomes a problem of the one who implements the interface, because it still needs to override the method. Also, the implementing interface can choose which base method (supermethod) to use, which means that most classes implementing the interface can change.

A lot of people worry about this detail in Java 8. Perhaps this will not disturb those familiar with the Scala language. Functional interfaces can be directly compared with the concept of traits in Scala. However, there are several differences: the functional interfaces in Java 8 cannot get a reference to the implementing class, however Scala allows this using the self keyword. Bores can argue that in Java 8, functional interfaces allow multiple inheritance of behavior, but prohibit state inheritance, while in Scala both are allowed.

Lambda


The purpose of lambda expressions is a more elegant code. When you compile, the lambda expression is converted to a functional interface. Here is an example where an anonymous class is replaced by a lambda expression.

Old style:
 button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { System.out.println(“Action Detected”); } } ); 


A new style:
 button.addActionListener(e -> { System.out.println(“Action Detected”); } ); 


And one more example.
Old style:
 Runnable runnable1 = new Runnable() { @Override public void run() { System.out.println("Running without Lambda"); } }; 


A new style:
 Runnable runnable2 = () -> { System.out.println("Running from Lambda"); }; 


As you can see, using lambda expressions makes the code more readable, and shorter. This excited a lot of people in the Java community. Scala already has all these features. And it's no surprise that the Scala community is skeptical , because a lot of the innovations in Java 8 look like a replacement operator => to -> in Scala. In some cases, Java 8 syntax looks more verbose or less pure than in Scala. It is not yet clear whether everything will be as it is in languages ​​like Scala, built on lyabda-expressions.

On the one hand, if Java continues to evolve and implement everything around the lyabmda expressions, as was done in Scala, then perhaps there will be no need for Scala. On the other hand, if the lyabmda expressions are only to provide basic functionality, such as help with anonymous classes, then Scala and other languages ​​will continue to thrive, as they are doing now. This is the best way, it will allow other languages ​​to grow and be inventive without worrying about whether they can become obsolete.

Java time


Java has a long history associated with time. First, there was the java.util.Date class, which quickly showed that Sun may declare methods obsolete in record time, but these methods can remain forever. And do not forget java.sql.Date , which helped to find out the time and place for using the fully qualified names (FQNs) in the code.

Then it was Calendar , which realized that the code could work with more than one part of the world in one JVM. But working with time and dates required a large number of monkey code and messing around with a scattered API. Therefore, third-party libraries such as JodaTime were born. Now Java, with a delay, decided to restore order in the java.time package. To me, it looks like the time API we always wanted.

Nashorn


Netscape created a technology called LiveScript that allows you to work with scripts on their web server. It was decided to port it to their browser, and a more beautiful name was required, so LiveScript was licensed under the Java trademark from Sun and called JavaScript — which caused confusion about the relationship between Java and JavaScript. However, after the collapse of AOL, some members of the Netscape team continued to implement the Netscape plan to rewrite the browser in Java. In order to do this, it was necessary to implement JavaScript in Java, Netscape called this project Rhino.

Modern JavaScript, this is not the kind of JavaScript your father knew. It can be useful both on the client side and on the server side, and you can develop applications that are readable and fast. In JDK 7 added invokeDynamic - support for dynamic languages. And in JDK 8 will provide a more useful implementation of JavaScript and that, perhaps, will make Nodyn (Red Hat's port of Node.js to the JVM) not just a terrible hand-made article. In general, Oracle has its own Node.js implementation , creatively named Node.jar. What most people are sure of is that they want to run all sorts of things on the JVM, but they don’t want to use Java syntax for this.

There are places where running JavaScript from Java is useful. For example, you can use client-side validator, as server-side validator, i.e. have the same code running in two places. Having your own Node.js with Java is how to get a cute monster who doesn't want that? If you are not sure whether I am serious or not in reading this text, then it makes us look alike.

Accumulators


First was synchronized. However, if all you need to do is increase the counter from many threads, then synchronized is heavy for this task. It became not so heavy in Java 6, making innumerable locks cheaper. This basically helped the old applications still using Vector, this is a single-threaded junk file that hit every library in the Java Activation Framework.

With the advent of the java.util.concurrent package, it has become better - the thread pool and other complex multi-threaded constructs, but if all you want is just an increase in the counter threads, it was all unnecessary. To do this, we were given atomic-i - quick and easier than real lock. However, Doug Lea and his favorite army of graduate students have not finished yet. In JDK 8 we will be given accumulators and adders . They are lighter than atomic, and with weakened guarantees, this is what parallel code needs most, which increases the total counter. I expect to see this innovation in map / reduce implementations. However, you still need atomic-and, if you want to read the value of the counter in the streams, since the order of accumulation of the counter is not guaranteed.

Hashmap fixes


There is a known bug related to how String.hashCode () is implemented in Java. If a large number of parameters have the same hash, it will cause excessive load on the CPU when working with HashMap. Such a situation may arise if the application is subjected to a denial-of-service attack, as in this case .

Now, baskets in a HashMap use a linked list to store values. If there are a large number of collisions, then the complexity of working with the structure varies from O (1) to O (N) . Now, when a certain number of items in the basket is reached, the basket switches to using a balanced tree, which reduces the complexity to O (log n) .

TLS SNI


SNI is not the name of the character Dr. Seuss, and Server Name Identification . Everyone loves SSL or TLS, or whatever it is now called. Many sites use the same IP and name-based virtual host. Which means that the second line of the HTTP request is the host name. I can make a request to podcastd.infoworld.com and www.infoworld.com , but are the same IP, but get different pages, because of the different host name. However, I can not keep many sites on the same IP because of SSL. For each SSL certificate I must have a separate IP address. And if you recall the sad situation with the current number of IP addresses in IPv4, then everything becomes even sadder.

But now Java supports SNI. Most modern browsers support SNI, Apache supports and Java now also supports. This means, what we have been waiting for so long - Tomcat and other Java-based servers using Oracle's slow SSL implementation ( JSSE ) now support SNI.

Conclusion


In general, delicious buns are expected in Java 8, but then the rake also hid. In my opinion streams are a better addition. I hope the concurrency of collections will increase the speed of their processing. Transfer your data set to memory, and when you need to extract something from this data, run the streams in parallel mode and obtain the necessary data. What causes concern are functional interfaces. When not properly used can cause a bunch of headaches.

From translator


This is a translation of this article.
I saw in the comments the desire of the habrovchan to learn about the Java 8 buns, and he wanted to, and then this article came across, so I sat down and translated. The translation is not literal, but I tried to make it as close as possible to the text, I gently had to throw it out, because The author of the article is joking, but his jokes are hard to translate. Therefore, experts in English strongly recommend reading the original.

Source: https://habr.com/ru/post/188850/


All Articles