We're going to be performing some really long operations that depend on a data set that has roughly
one million records.
So you already know whatever operations we're going to make, they're going to be really long and they're
definitely not going to be on the main thread.
Otherwise, you're going to be blocking it.
OK, if you go back to the application, you'll notice the main threat already has a line of code that
grabs the path of as v file.
And using this path object, what we can do is run through every line in the CSV file as a stream of
elements.
So back to mean not Java, don't show again.
Well, so by creating the average function.
Public static seems that the function expects or returns a double.
It's called average, it expects a path variable.
Named Path.
As well as string variable named category.
And inside the function, the first thing we're going to do is a run through every line from this year's
V file as a stream of elements.
I left you a hint inside the article and that was to use the files class.
Pilots without lines inside, we pass in the path to our skies, we file.
And if you look at the documentation, this reads all lines from a file as a stream of elements.
And it seems like Lines throws a checked exception, so what we're going to have to do is try to run
the code.
Before we start our stream pipeline and catch the exception, if the code fails, catch IO exception
is what it was.
And will perform some logic here later.
First thing we're going to do is as we're running through this stream of elements, we want to skip
the very first line.
Because you'll notice and let me just scroll up, you'll notice the very first line is just a series
of column headers, category price of item in each category and quantity of items sold.
The way we can do that is say, don't skip.
And inside, you want to specify the element in the stream that you want to skip.
We want to skip the very first elements.
Skip one.
Now, the next thing we want to do is we want to map every single element in this dream to an array
of three string values.
So we're going to map every single element in this dream.
Remember, here we have to specify a lambda expression that receives every single element, which is
just a line.
We always have the arrow that points to a value we want to return, and we're going to map every single
line to an array of three string values line dot split and we're going to split every element into an
array of three strings separated by a comma.
OK, now every element in the stream should be an array of three values.
And so now what we want to do is we want to filter the stream by category.
So if the user were to pass any category of furniture, we want to filter the stream to only have furniture
elements.
So what we can do is say, don't show again, this keeps popping up.
Don't Filter Filter is going to receive an array of three string values.
And we want to filter the elements whose values.
At Index Zero.
Equals the category that gets passed in.
And now we want to do is map every element in the stream to a double price times quantity.
So now what we want to do is map every single element in the updated stream to a sales value.
So we're going to say map to double because we expect to map every single element in the stream to a
double value.
And we're going to map every single element, which is currently an array of three string values to
a double value by multiplying.
The value at index one, let me just make sure of that, yet the value of the index one times the value
at index to.
Times.
Let's me remove that.
Times the value at index to.
OK.
And now every single element in the stream should now be a double value to that stream, we're going
to apply a terminal operation called average.
And what it's going to do is basically take the average of every single element in the stream.
But average returns an optional double.
So we're going to use get as double to return a concrete double.
And that's it.
And now what we want to do is return the results of this dream pipeline.
We do get an error here, and that's because our expression doesn't know that each element in values
is actually a quantity.
It interprets them as a string.
So what we can do is, say, double the value of.
Values one.
We're passing a double from each string value times, double the value of values to.
And we should be good, and now we get another compilation error, because in the event of an exception,
catch is going to get called, in which case we still need to return some sort of value.
So for now, we'll just print the message that comes out of this exception, exception get message and
then we'll just return zero if the user gets back zero.
It's a pretty clear indication that something's wrong and there should be it.
And it seems like for a task to we need to create a very similar function where this function takes
the average sales for one category.
This function takes the total average across the entire sets.
So in very similar fashion, we'll create a public static method that returns a double.
This one is called total average.
It receives a path object.
And once again, we will try to run the files, the lines code.
And in the event of an error, we're going to catch the oh exception.
In which case we're going to print system.
I doubt that print line inkjet message and return zero point zero.
OK, and in this case, once again, here we're running through every single line from this year's V
file as a stream.
First, we map every single element to an array of three values.
So we're going to map every single line.
Every single element to an array of three string values, line darts split.
And we're going to split values around a comma.
There is no need to filter anything here, we can just directly map every single element in this dream
to a double value.
So the lambda expression is going to receive an array of three values and we're going to map every single
element to the multiplication of values one times values to.
But you can't multiply string value, so what we need to do is pass a double from each string.
And now what we want to do is apply the terminal operation average.
In return, the average double.
OK.
Don't forget to return the result of the stream pipeline.
And it seems like we're good.
OK, let me just double check everything, make sure it's good.
First, we're skipping the very oh, we forgot something.
We need to skip the very first line because there is nothing that we can do with it.
And I think now we should be good.
Now inside men, I'm going to call the average method for furniture.
I'm not going to print anything, I'll just say average path furniture.
I'll copy and paste this two more times, I'll take the average very technology.
The average for office supplies.
And then I can calculate the total average.
By just reading every single line from the path.
And after we call all of our methods, we need to copy some code into men.
I left you this code inside, learn the parts, so make sure to copy it.
And so the idea is that when the user first starts interacting with our app, they're expecting to start
interacting with it right away.
But these tasks take so long to execute that they're going to block the main thread and basically ruin
the user experience.
So let's see that in action.
We're going to run the code.
And wow, this was really bad user experience.
The user shouldn't have to wait so long before they can answer the question, and that is why we need
to ensure that long running tasks do not block the main threat because blocking the main thread negatively
affects user experience.
That's something you have to keep in mind as you're building apps in the future.
And so we can conclude that these calculations are time intensive.
So what we're going to do is run each calculation on another threat.
So remember, we can just.
Create three threat objects thread threat two is equal to a new object of the thread class that expects
a runnable.
We can copy and paste that two more times at three thread for here will perform the task for a technology
will perform the task for office supplies.
And then our last thread will perform the task.
Of calculating the total average will remove that.
That's it.
Now we can call.
Threat to not start.
Threat three starts.
Pretty tedious, but don't worry, in the future, I will show you a much better way of running stuff
on the background.
In the background, I should say.
And if we run the app now.
So enough to rerun it.
And this is beautiful, because as the user is answering this question, these tasks are executing in
the background.
So by the time they actually answer, it's.
The user experience is seamless.
These tasks have already finished running, and that is why you never blocked the main thread.
You make sure that long running tasks execute in the background.