• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Devaka Cooray
  • Ron McLeod
  • Jeanne Boyarsky
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Carey Brown
  • Tim Holloway
Bartenders:
  • Martijn Verburg
  • Frits Walraven
  • Himai Minh

How to add up values from a field in a not duplicate list?

 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all!

I have an entity that has 2 fields: Wrapper Entity :

Then,the Element Class:

In the main Class,i have a List of "Wrappers":


Now,i transform this list into a Map,grouping by Wrapper ID

After this ,i have a map with 2 elements:

-The first One with KEY=1 -> List with 2 elements

-The second One with KEY=2 -> List with 4 elements.

This is what i need now:

As you can see,the Element Class,has a field "quantity",and i need to add up this field when the Elements belong to the same Wrapper ID and the Element name it s the same.
For example the above map,should result in:

-The first One with KEY=1 -> List with 1 element ,the quantity Field = 3 (The first Element has a 1 in quantity value and the second has a 2)

-The second One with KEY=2 -> List with 2 element,the first one with name "Name 2",quantity 12 ,the second one with name "Name 3",quantity 6

What i did to achieve this is the following:

-The List ,now it s a Set

-Overrided Equals method ,when Objects are the same,i add up the quantity field of Old value and New Value ,and return true. Here the changes i made:

The following into the Element Class:

Is this approach OK? Or it s a better one?
Thanks in advance!
 
Marshal
Posts: 76862
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't know any Angular, but I can see problems which are plain simple Java®/object‑oriented programming, which I do know.

Ale Garcc wrote:. . .
The following into the Element Class:

Is this approach OK? . . .

No.

Why are you using an Integer for id rather than an int?
Don't simply copy the reference for mutable types, which includes Set. If anybody makes any changes to the Set, your copy will change, because it is the same object, and you won't know anything about it. At least not until something goes wrong. Similary don't simply return the Set reference; that can cause exactly the same problem. There are several ways to return a Set, but this is one way of ensuring that the Sets are all distinct from each other:-You may still have problems if any of the elements in the Set changes its state; that class is also mutable.

Your equals() method is wrong because it doesn't do what the general contract for equals() requires. It has a side‑effect. If you want that, write a method called something like addQuantitiesIfSameName() or similar. The length of that method name makes me wonder whether anybody should be adding quantities at all. What will happen if you call that method twice? It is better to iterate the set and collect quantities. Have a look at the counting words example in this tutorial. You can use something like that to collect the quantities in a Map.
Using getClass() is controversial. If you have subclasses of Element, even if they have the same content, you will get false returned from equals(). That is not a problem if you declare the current class final. I also like structured programming, so to avoid multiple return, I would write something like this:-Line 7 does the same as your lines 3‑4. If you reduce equals() to one statement, you need two casts . You need two pairs of () for the casts ((Element)ob).something to raise the precedence of the cast to higher than that of the dot operator. If you use instanceof, (1) you can get equality with subclasses and (2) you don't need to test whether ob is null. You will still get problems if either field is null; I think the simplest way to cure that problem is to use this method, but you will still need the casts. This is the only place I can think of just at the moment, where it is respectable practice to use instanceof. Remember you should also override hashCode(); the alphabet of variables used in hashCode() should be the same as the variables in equals().


Many people will disagree with me about structured programming and are happy with multiple return.

By the way: if you use a Set, you won't have any duplicates to add up.
 
Campbell Ritchie
Marshal
Posts: 76862
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I merged your stuff with the following thread. I hope that is okay by you.
 
Ale Garcc
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all!

I have an entity that has 2 fields: Wrapper Entity :

Then,the Element Class:

In the main Class,i have a List of "Wrappers":


Now,i transform this list into a Map,grouping by Wrapper ID

After this ,i have a map with 2 elements:

-The first One with KEY=1 -> List with 2 elements

-The second One with KEY=2 -> List with 4 elements.

This is what i need now:

As you can see,the Element Class,has a field "quantity",and i need to add up this field when the Elements belong to the same Wrapper ID and the Element name it s the same.
For example the above map,should result in:

-The first One with KEY=1 -> List with 1 element ,the quantity Field = 3 (The first Element has a 1 in quantity value and the second has a 2)

-The second One with KEY=2 -> List with 2 element,the first one with name "Name 2",quantity 12 ,the second one with name "Name 3",quantity 6

What i did to achieve this is the following:

-The List ,now it s a Set

-Overrided Equals method ,when Objects are the same,i add up the quantity field of Old value and New Value ,and return true. Here the changes i made:

The following into the Element Class:

Is this approach OK? Or it s a better one?
Thanks in advance!
 
Campbell Ritchie
Marshal
Posts: 76862
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This looks exactly the same as your earlier post, which I have already replied to. I think it best I merge your earlier post with this one, so there won't be any duplicate questions.
 
Ale Garcc
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I don't know any Angular, but I can see problems which are plain simple Java®/object‑oriented programming, which I do know. . . . .



Hi ! Thanks for your answer!
This is Java code,i dont know why it s inside Angular Forum!
The context about my question,it s data that it s coming from a Http Request and i need to iterate the answer to make some grouping,changes,adding etc.
The example i wrote it s something simple i did for this forum.
About your response,where should i add the addQuantitiesIfSameName() ,and how and where should i call that method?
And about your second option, "It is better to iterate the set and collect quantities",i dont imagine where do that,because once the list it s complete,i will need to iterate,collect and remove Duplicates objects inside Set.
I really appreciate the time you took to answer my question,because i really need to solve this problem.
Thanks !
 
Campbell Ritchie
Marshal
Posts: 76862
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Have removed most of the quote; nobody wants to see what I wrote twice Moving you to a Java® forum.

Ale Garcc wrote:. . . Hi ! Thanks for your answer!

That's a pleasure

. . . The example i wrote it s something simple i did for this forum.

Beware of simplifying questions, though you may have to do that to keep proprietary content confidential. If you ask too simple a question, you may get too simple a reply which doesn't provide all you need.

. . . where should i add the addQuantitiesIfSameName() . . .

Not sure. Probably nowhere at all.

. . . iterate the set . . . i dont imagine where do that . . .

Consider filling the List, and as you go, summate the results. Did you see the word counting example in the Java™ Tutorials I told you about yesterday? It counts words, so it adds 1 to each “V” as it goes, but adding counts is only slightly harder. It will go something like this:-You will need some version of equals() in the element objects that will implement the definition of equality you need (and hashCode()).

You can create a Counter object that totals the counts, and use a Map<String, Counter> instead. There are probably other ways you can add counts with Streams and the collect method and Collectors.groupingBy. Or you might be able to use the putIfAbsent method of the Map.
 
Campbell Ritchie
Marshal
Posts: 76862
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Have removed most of the quote; nobody wants to see what I wrote twice Moving you to a Java® forum.

Ale Garcc wrote:. . . Hi ! Thanks for your answer!

That's a pleasure

. . . The example i wrote it s something simple i did for this forum.

Beware of simplifying questions, though you may have to do that to keep proprietary content confidential. If you ask too simple a question, you may get too simple a reply which doesn't provide all you need.

. . . where should i add the addQuantitiesIfSameName() . . .

Not sure. Probably nowhere at all.

. . . iterate the set . . . i dont imagine where do that . . .

Consider filling the List, and as you go, summate the results. Did you see the word counting example in the Java™ Tutorials I told you about yesterday? It counts words, so it adds 1 to each “V” as it goes, but adding counts is only slightly harder. It will go something like this:-You will need some version of equals() in the element objects that will implement the definition of equality you need (and hashCode()).

You can create a Counter object that totals the counts, and use a Map<String, Counter> instead. There are probably other ways you can add counts with Streams and the collect method and Collectors.groupingBy. Or you might be able to use the putIfAbsent method of the Map.
 
Ale Garcc
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Have removed most of the quote; nobody wants to see what I wrote twice Moving you to a Java® forum.

Ale Garcc wrote:. . . Hi ! Thanks for your answer!

That's a pleasure

. . . The example i wrote it s something simple i did for this forum.

Beware of simplifying questions, though you may have to do that to keep proprietary content confidential. If you ask too simple a question, you may get too simple a reply which doesn't provide all you need.

. . . where should i add the addQuantitiesIfSameName() . . .

Not sure. Probably nowhere at all.

. . . iterate the set . . . i dont imagine where do that . . .

Consider filling the List, and as you go, summate the results. Did you see the word counting example in the Java™ Tutorials I told you about yesterday? It counts words, so it adds 1 to each “V” as it goes, but adding counts is only slightly harder. It will go something like this:-You will need some version of equals() in the element objects that will implement the definition of equality you need (and hashCode()).

You can create a Counter object that totals the counts, and use a Map<String, Counter> instead. There are probably other ways you can add counts with Streams and the collect method and Collectors.groupingBy. Or you might be able to use the putIfAbsent method of the Map.


Thanks again!
The problem with that approach ,it s that i will end up wih a map of Name->Total.
And i want the object itself contains the total inside the quantity field.

Exploring your answers i ended up with the following solution :

Basically,what i am doing it s the following:
1-Iterate the map
2-For each element in the map,iterate the list of Elements
3-Collect those elements inside a map,where the name is the Key,and the Element the value
4-And when values are the same,i add up the quantity field from oldElement with the quantity field of newElement
5-Convert the map to a List of Elements
6-Set the new modified list of Elements to the Wrapper object.
Let me know what you think ,thanks !
 
Campbell Ritchie
Marshal
Posts: 76862
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ale Garcc wrote:. . .
i will end up wih a map of Name->Total.
And i want the object itself contains the total inside the quantity field.
. . .

Please explain your design more; I can't see how you are going to have accurate quantities inside the element objects.
 
Ale Garcc
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Ale Garcc wrote:. . .
i will end up wih a map of Name->Total.
And i want the object itself contains the total inside the quantity field.
. . .

Please explain your design more; I can't see how you are going to have accurate quantities inside the element objects.



Campbell Ritchie wrote:

Ale Garcc wrote:. . .
i will end up wih a map of Name->Total.
And i want the object itself contains the total inside the quantity field.
. . .

Please explain your design more; I can't see how you are going to have accurate quantities inside the element objects.



Hi!
Yes,i can explain a little more:


1-Iterate the map
2-For each element in the map,iterate the list of Elements
3-Collect those elements inside a map,where the name is the Key,and the Element the value
4-And when values are the same,i add up the quantity field from oldElement with the quantity field of newElement

Suppose ,we are iterating the second element inside the resultMap map.
After getting that object,we iterate the Elements list of that object.
While iterating that list of "Elements" ,we create a Map,with the "name" as key ,and the Element itself as the value.
When elements are the same,the following line will be executed :

There ,i am adding up the quantities,when the elements are the same.
The resulting map would be :
Map of 2 elements:
-The First one with key="Name 2",value =Element (with quantity value 12)
-The Second one with key="Name 3",value =Element (with quantity value 6)

Then,i convert this into a List,having this new List,i set it into the Wrapper object

Let me know if it s more clear now ,thanks !
 
Campbell Ritchie
Marshal
Posts: 76862
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Afraid that doesn't explain what you are doing, only how you intend to do it., When you work out the “how” before the “what”, you are skating on thin ice, with potentially brittle and error‑prone solutions. What's more, your solution destroys the evidence of the previous counts, so you will find it difficult to identify errors.
It does look like the counting words example I told you about last week.
You could make much more reliable and robust code if you made those objects immutable, and got rid of the setXXX() methods. I suggest you might want a combine() method which creates a new object combining the two counts, but insisting on the same name in both its arguments.
 
Ale Garcc
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Afraid that doesn't explain what you are doing, only how you intend to do it., When you work out the “how” before the “what”, you are skating on thin ice, with potentially brittle and error‑prone solutions. What's more, your solution destroys the evidence of the previous counts, so you will find it difficult to identify errors.
It does look like the counting words example I told you about last week.
You could make much more reliable and robust code if you made those objects immutable, and got rid of the setXXX() methods. I suggest you might want a combine() method which creates a new object combining the two counts, but insisting on the same name in both its arguments.



Not explaining what i am doing???
Yes...you are right...merry Christmas..
 
Campbell Ritchie
Marshal
Posts: 76862
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually, I am less confident about the combine() method than yesterday; I don't think it will be a reliable alternative after all.
 
Whatever you say buddy! And I believe this tiny ad too:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic