preface

I recently saw a concept called Sequence. That’s interesting. Google wrote a very good article, translated it and posted it to everyone.

Original address (self-provided scientific Internet) : medium.com/elye.proje…

A, List

Before we get into why sequences are better (in some cases), let me tell you a few things about lists.

Let’s look at the List and Iterator application:

val list = listOf(1.2.3.4.5.6)
list.map{ it * 2 }.filter { it % 3= =0 }.average()
Copy the code

I’ve been doing it carefully, step by step, and just to make it more obvious let’s log a little bit.

val list = listOf(1.2.3.4.5.6)
val result = list
        .map{ println("In Map"); it * 2 }
        .filter { println("In Filter"); it %3= =0 }
println("Before Average")
println(result.average())
Copy the code

Take a look at the results:

Every step was taken. There seems to be nothing strange about this. But let’s look at something interesting: Sequence.

Second, the Sequence

2.1. General use

Here we can use asSequence() to turn our List into a Sequence. The code:

val list = listOf(1.2.3.4.5.6)
val result = list.asSequence()
        .map{ println("In Map"); it * 2 }
        .filter { println("In Filter"); it %3= =0 }
println("Before Average")
println(result.average())
Copy the code

Take a look at the log result:

Before Acerage is typed first. This is interesting…… In other words, if we do not call Average (), nothing will be done to the Sequence.

Yes, it is lazy, and the Sequence will not make any calls as long as the consuming operation is not invoked actively. (This is similar to lazy loading.)

At this time there may be a small partner carrying a 40-meter long knife: I tm is to execute the traversal, you give me a lazy load is how many meaning?

Brother Dei, put down the knife, don’t worry, I continue to blow to you, no, no, no… Keep talking to you.

Let’s not just stare at lazy loading and wonder if we notice it interleaving execution In Map and In Filter. This means that it does not iterate through the first collection and then iterate through the second collection. Instead, you take multiple traversal operations, tie them into a chain, and walk through the chain… It might be hard to understand, but our last picture:

2.2. Sequence Advantages

I guess people are still n face blind… Let’s change the demo a little bit. In the first demo, let’s use List for comparison:

val list = listOf(1.2.3.4.5.6)
val result = list
        .map{ println("In Map $it"); it * 2 }
        .filter { println("In Filter $it"); it %3= =0 }
println(result.first())
Copy the code

Call the first() method. Take a look at log:

Is normal. Let’s look at the “abnormal” Sequence:

val sequence = sequenceOf(1.2.3.4.5.6)
val result = sequence
        .map{ println("In Map $it"); it * 2 }
        .filter { println("In Filter $it"); it %3= =0 }
println(result.first())
Copy the code

2.3 map comparison

See what’s interesting about Sequence? In fact, the optimization point of Sequence lies in map. Let’s continue with a set of tests:

val sequence = generateSequence(1) { it + 1 }.take(50000000)
val list = sequence.toList()

println("List Map Sum= " 
        + measureNanoTime { list.map { it * 2 }.sum() })
println("Sequence Map Sum " 
        + measureNanoTime { sequence.map { it * 2 }.sum() })

println("List Map Average " 
        + measureNanoTime { list.map { it * 2 }.average() })
println("Sequence Map Average " 
        + measureNanoTime { sequence.map { it * 2 }.average() })
Copy the code

As can be seen, under map, Sequence is 4-7 times faster than List. But is a Sequence necessarily better than a List? Let’s try a different operator:

2.4 filter comparison

val sequence = generateSequence(1) { it + 1 }.take(50000000)
val list = sequence.toList()

println("List Filter Sum " 
        + measureNanoTime { list.filter { it % 3= =0 }.sum() })
println("Sequence Filter Sum " 
        + measureNanoTime { sequence.filter { it % 3= =0 }.sum() })

println("List Filter Average " 
        + measureNanoTime { list.filter { it % 3= =0 }.average() })
println("Sequence Filter Average " 
        + measureNanoTime { sequence.filter { it % 3= =0 }.average() })
Copy the code

It can be seen that in filter, List is higher than Sequence.

conclusion

  • If no additional operators are required, use List
  • If you only have the Map operator, use Sequence
  • If only the Filter operator is available, use List
  • If you need an operator like first(), consider using Sequence as appropriate.

I am a fresh graduate, recently and friends maintain a public account, the content is that we in the transition from fresh graduate to the development of this way stepped on the pit, as well as our step by step learning records, if interested in friends can pay attention to it, together with fuel ~