Java threads vs iterators

I play with the new and brilliant functional part of Java, and one of the things that excites me the most is flows?

What is their use?

At Google, I basically found explanations on how to use them and practical examples that I have already come up with, nothing concrete about the magic behind the scenes that interests me.

I do not mean in a practical sense, based on several functional languages, I understood the map / filter / reduce / etc. pretty fast, but why do we need to convert to a stream first? Java already has iterators. Is there a fundamental difference between a thread and an iterator, like one lazy and the other not? Or is it something else?

Bottom line: what is the fundamental difference between iterators and threads, and what functionality cannot be implemented as an extension to iterators and does it require a whole new type family?

+7
java iterator stream java-8 java-stream
source share
5 answers

Speaking of threads, in general, this is an extensive topic. However, I will describe why you should approve the stream APIs through Iterators.

First of all, using the stream API, we can now program at a much higher level of abstraction, just like SQL queries, i.e. we express what we want and let the library handle the rest.

Secondly, stream operations perform their iterations behind the scenes (internal iteration), which means that data processing can be performed in parallel or in a different order, which can be more optimized.

On the other hand, if you decide to explicitly iterate over your collection to perform some calculations, whether using Iterator or syntactic sugar for an iterator (extended loop), you explicitly accept the elements in the collection and process them one by one, so it is essentially serial.

Using iterators instead of the stream API also means that you have to work hard when you want to go parallel or find various ways to optimize your program.

However, it also means that you spend a lot more time on low-level details, rather than just focusing on what you want your program to do.

Also mentioned in Java-8 in the action book:

The internal iteration in the Streams library can automatically select the data presentation and parallelism implementation to match your hardware. In contrast, as soon as you choose an external iteration to write for each, then, in fact, you undertook to independently manage any parallelism. (Self-government in practice means “one fine day,” “parallelize it well” or “start a long and difficult battle including tasks and synchronized ones.”)

Java 8 needs an interface like Collection, but without iterators, ergo Stream!

In essence, with the streaming API, your life is much simpler in many ways, but what I find most useful is the fact that now you can devote more time to focusing on what you want your code to do, and at the same time, you may decide to go parallel without dealing with low-level materials.

This, of course, does not mean that you should always use streams wherever possible. Rather, it points to the advantages of using threads over iterators.

There are certain places where it would be more appropriate to use iterators rather than the stream API and vice versa. Therefore, it is wise to choose which approach you need to start processing data in collections.

+8
source share

Adding Stream methods to an existing Iterator was certainly possible because default implementations can be provided for all additional methods, but this API change has significant drawbacks:

  • Your threads become “married” to iterators even in situations where you do not need an iterator (for example, a generator thread)
  • You don’t get streams from collections “for free” - just like you call Stream , you will need to call Iterator (which is already the case for extended loops using iterators)
  • You still need a lot of new types for primitive flows, because iterators don't have a similar concept. This is functionality that would be difficult to “translate” into iterators.

The overall benefit of merging streams with iterators did not look much, so it seems that the API designers have taken a clean approach to sheets.

+5
source share

Is there a fundamental difference between a stream and an iterator from one lazy, and the other not? Or is it something else?

Yes, the main difference is that the threads are processed internally. What we say when we start the flow is that we want to filter it all into this material, on this conditional, and give us this result. We, of course, are not talking about how we want this to happen. This means that the same source code can later be run in parallel on a graphics card or in some other unknown way. We just want this to happen.

There are many interesting things that can happen behind the scenes if we, as programmers, are frank by the criteria that we do not need. It is also a large part of functional interfaces and some lambda expressions. The idea is that if we say that we do not care at first, then compilers can solve this problem anyway that solves it, and not how the program announced its solution. Sometimes, various computer devices can solve things differently, for example, better parallelize.

Bottom line: what is the main difference between iterators and streams and what functionality cannot be implemented as an extension to iterators and did you need a completely new type family?

Iterators said the problem should be resolved. He needed to make this element, then this element, then this element, and the compiler cannot know if there is any deep and seemingly hidden reason for this, and not in some other way. The threads say that you don't care, iterating back and forth, onto a thousand different processors, on the GPU, it doesn't matter.

I want each item to be handled this way. I want one element after another to be handled this way. The latter is really useless.

+4
source share

In my opinion, Java 8 threads are conceptually very similar to Unix feeds. You start with a specific set of data that you filter, manage or execute until you reach the exact result that you like. The resulting code is also much less verbose than would be possible using traditional constructs. Others have already mentioned that threads relate to what is in contrast to how.

One specific example of what I used my work on is cleaning websites. The JSoup library provides the result of a CSS query as a type that implements Collection . Now, if you use it in Java 8, you get free downloaded streams.

This means that you can select specific tags using a CSS query, filter out certain tags that you are not interested in, convert them to some object and fill them in a list: all this is just a few lines.

It is possible to do this in Java 7, but you need to declare a list, iterate over the tags, conditional statement, create an instance of the object, add it to the list ... You can easily have three times as many lines.

The benefits of not having to deal with the implementation are valid and correct, but in a more business-oriented approach, it makes your code much more readable and therefore easier to maintain, including by other people. Bosses are like that.

The flip side is that due to Java's conservative approach to new features, there is a lot of syntactic sugar that hides the implementation until you get an exception stack trace and you want to study English literature instead of software development.

+4
source share

In addition to the other answers, I will also write a more cynical answer. For the most part, this is due to the amount of input that programmers have to do, and how concise the code looks. Many languages ​​out there support lambdas and streams already. And the people who write in these languages ​​say things like “Java sucks because you have to write all this code to process all the items on the list. My language supports functional programming and why it is better than Java.” Java does not require Streams or lambdas, everything is fine with them. But he must remain competitive. There are many Java programmers there, and we don’t like the way our language gets dragged into the mud. And I agree that although they do not need threads, they are very interested in writing. Streams, in the end, result in less typing, and you do your job much faster. Its smooth and beautiful.

There is a problem with Streams and lambdas, which may require repetition from time to time. And this is that lambdas works with leaf objects and leaf primitives, that is, objects and primitives that are outside of lambdas must be final. For the most part, you might be able to get around this, but from time to time you can just go back to iteration, because it is just easier. Don’t worry about it, when this happens, you will see it because your code will not compile.

+1
source share

All Articles