Whatever you are doing, if you want a maximum value, you need some way to compare those values to decide whether,
value1 is “greater than” value2, or
value1 is “less than” value2, or
value1 is “the same as” value2.
I suggest you go through the Collections part of the Java™ Tutorials, particularly looking at the section called, “Object Ordering”. Then come back when you have understood that section and decided how to order any two of your objects.
Do your objects have a “natural ordering”? That means that every two objects fulfil the three bullet points above, and that if you don't change anything you get the same results, and there is one single criterion used for the ordering. Some kinds of object have multiple possible orderings.
Sot Nikele wrote:And another question, again using Streams, how can I remove those items having the max value?
Streams aren't generally meant to modify the object from which they are streaming their data. Instead of trying to fight against that principle, I would say you are better off producing a new List<Item> which contains only those items which don't have the max value.
This would require one Stream which produces the max value, and then a second Stream which filters objects which don't have the max value into that new list.
as Campbell writes, thre are easier ways to achieve the result, but I surely like your method.
You could make the code a little more readable by creating two BiConsumers:
and use these in your '.collect'.
Another way to shorten your code is to have
I used your idea, but instead of creating an ArrayList with the maximum objects, I created a TreeMap<Integer, List<Object>>, so that that map's lastEntry gives us the max objects.
For that I created a record and a helper class to keep the typing to a minimum:
Using the 3-parameter version of collect, I needed, as you did, to write a BiConsumer<Short, Mehmet>, and a BiConsumer<Short, Short>. Since
you are using a parallelStream, that last one was a little nasty.
Well, I hope you find this instructive:
I find your code extremely confusing Piet. Please don't use existing type names for custom types. The name Short to me means java.lang.Short, which is the primitive wrapper type for the short integral type. It took me a while to realize it was a kind of type alias for a Map instead.
I'm also not a fan of declaring variables to hold functional types. Instead, just write a private method instead of a lambda expression and use a method reference.
Don't use method references or lambdas to refer to a method of a functional type. Pass the function object directly. In your code, you use sup::get in collect(), while passing sup directly will suffice.
Note that your collection operation can be replaced by just the following:
Or, if you want improved performance at the cost of losing encounter order:
The second option still maintains correct ordering of the keys, so you can still use lastEntry() to get the list of maximum elements, the list itself just won't maintain encounter order.
Now, if I didn't have access to the groupingBy() collector, I would write the code like this:
As you can see, the accumulate() and combine() methods closely resemble your consumers, except I made them into methods on a local Accumulation class.
This collector can easily be used in your main method and gives the exact same results as your original code:
Well, if YOU say it's confusing, then I guess it must be.
As you can see, I did use the groupingBy in an earlier example, but here I followed OP's way with the .collect(supplier...), involving two BiConsumers.
And I like using variables for functional interfaces, makes the code much more readable. You are right about my Short; can't remember ever having used a Short, I guess I forgot its existance. But the name 'Short' instead of ' TreeMap<integer, List<Mehmet>> seemed very reasonable.
But as said, point was to use the 3-parameter version of collect, something that you don't see too often.
There are three kinds of actuaries: those who can count, and those who can't.
First of all thanks for giving your class to my name I was too focus to collect list and you showed me TreeMap is better option. I loved your result.lastEntry() trick <3 I agree Stephan's mentions about your helper class naming conventions. Also i think your helper class is confusing, i want to see TreeMap<Integer, List<Mehmet>> instead of another class. I was tought writing lambda expressions in method's param's is better but my lambda goes for too long. I am on your side now
Your suggestions cool about Piet's helper class naming conventions. Accumulation class seems complicated to me but i will give a shot when i need to declare lamda more than one.