I have a person class
public class Person {
private int id;
private int amount;
public Person(int id, int amount){
this.id = id;
this.amount = amount;
}
//getters
}
And I have a mainClass like this
Map<String, Person> mapOfObjects = new HashMap<String, Person>();
mapOfObjects.put("map1", new Person(1, 1000));
mapOfObjects.put("map2", new Person(1, 1000));
mapOfObjects.put("map3", new Person(1, 1000));
mapOfObjects.put("map4", new Person(2, 1000));
mapOfObjects.put("map5", new Person(2, 1000));
mapOfObjects.put("map6", new Person(3, 1000));
Map<Integer, Integer> mapOfSum = new HashMap<Integer, Integer>();
int sum = 0;
List list = new LinkedList(mapOfObjects.keySet());
for (int i = 0; i < mapOfObjects.size(); i++) {
for (int j = 1; j < mapOfObjects.size() - i; j++) {
if (mapOfObjects.get(list.get(i)).getId() ==
mapOfObjects.get(list.get(j)).getId()) {
sum += (mapOfObjects.get(list.get(i)).getAmount() +
mapOfObjects.get(list.get(j)).getAmount());
}
mapOfSum.put(mapOfObjects.get(list.get(i)).getId(), sum);
}
}
System.out.println(mapOfSum);
It gives me output:
{1=8000, 2=8000, 3=0}
but i want something like this
id=1 amount =3000, id =2 amount = 2000, id =3 amount =1000
How can i remove the object from the map whose summation is already done once while running the first for-loop
Your loop is overengineered.
Try this:
for (Person person : mapOfObjects.values()) //for every person in the map...
{
int newAmount = 0;
if (mapOfSum.containsKey(person.getId())) //if its already in the sumMap
{
newAmount = mapOfSum.get(person.getId()) + person.getAmount(); //update the value
}
else
{
newAmount = person.getAmount(); //else set it as starting value
}
mapOfSum.put(person.getId(), newAmount); //put it in the sum map. If it's already there it will be substituted by new entry.
}
Output:
{1=3000, 2=2000, 3=1000}
EDIT
If you want the output in different format you can do something like this:
StringBuilder stringBuilder = new StringBuilder("");
for (Map.Entry<Integer, Integer> entry : mapOfSum.entrySet())
{
stringBuilder.append("id=").append(entry.getKey()).append(" amount=").append(entry.getValue()).append(", ");
}
System.out.println(stringBuilder.toString());
Output:
id=1 amount=3000, id=2 amount=2000, id=3 amount=1000,
EDIT2:
As suggested in comments by #NickHolt there is more efficient way that shortens execution time by eliminating the containsKey() check.
It can be done like this:
Integer personAmount = mapOfSum.get(person.getId());
if (personAmount == null)
{
personAmount = person.getAmount();
}
else
{
personAmount = person.getAmount() + personAmount;
}
mapOfSum.put(person.getId(), personAmount);
or in shorter form using ternary operator:
Integer personAmmount = mapOfSum.get(person.getId());
personAmmount = personAmmount == null ? person.getAmount() : person.getAmount() + personAmmount;
mapOfSum.put(person.getId(), personAmount);
You can use Google Guava multimap
Multimap<Integer, Integer> PersonMap = ArrayListMultimap.create();
PersonMap.put(1, 1000);
PersonMap.put(1, 1000);
PersonMap.put(1, 1000);
PersonMap.put(2, 1000);
PersonMap.put(2, 1000);
PersonMap.put(3, 1000);
Then you can use something like:
Hashset<Integer, Integer> PersonDictionary = new Hashset<Integer, Integer>();
for (Integer key: PersonMap.keySet())
PersonDictionary.Add(key, Sum(PersonMap.get(key)));
Where sum a function : Is there possibility of sum of ArrayList without looping
Instead of using two for loops, use single, for traversing the value set of the map, and find the summation
Map<String, Person> mapOfObjects = new HashMap<String, Person>();
mapOfObjects.put("map1", new Person(1, 1000));
mapOfObjects.put("map2", new Person(1, 1000));
mapOfObjects.put("map3", new Person(1, 1000));
mapOfObjects.put("map4", new Person(2, 1000));
mapOfObjects.put("map5", new Person(2, 1000));
mapOfObjects.put("map6", new Person(3, 1000));
Map<Integer, Integer> mapOfSum = new HashMap<Integer, Integer>();
for (Person person : mapOfObjects.values()) {
Integer value= mapOfSum.get(person.getId());
if (value == null) {
value = 0;
}
value += person.getAmount();
mapOfSum.put(person.getId(), value);
}
System.out.println(mapOfSum);
Related
Here I am collecting some data in the inner map and along with User ID, it putting to the Outer Map. Then Inner Map is clearing and filling another set of data and looping the same for number of users.
The issue is While clearing the InnerMap, the Value put in the outer map is also clearing. I think I'm doing some mistake. Kindly advice.
HashMap<MDocumentNumber, Integer> innerMap = new HashMap<MDocumentNumber, Integer>();
HashMap<Integer, HashMap<MDocumentNumber, Integer>> outerMap = new HashMap<Integer, HashMap<MDocumentNumber, Integer>>();
List<MDocumentNumber> docNumbers = new Query(getCtx(), MDocumentNumber.Table_Name, "IsActive = 'Y'", get_TrxName())
.setOrderBy("CreatedBy").list();
int createdBy = 0;
int nextUser = 0;
for (MDocumentNumber docNumber : docNumbers)
{
createdBy = docNumber.getCreatedBy();
MAttachment attachment = new MAttachment(getCtx(), MDocumentNumber.Table_ID, docNumber.get_ID(), get_TrxName());
int attchmentCount = attachment.getEntryCount();
int versionCount = docNumber.getVersionCount().intValue();
if(versionCount > 0 && attchmentCount < versionCount)
{
if(nextUser != 0 && nextUser != createdBy)
{
outerMap.put(nextUser, innerMap); // for a new user, put the inner map data to Outer Map
innerMap.clear(); // Here while clearing the inner map, the outer map value is also clearing
}
innerMap.put(docNumber, (attchmentCount-versionCount));
nextUser = createdBy;
}
}
outerMap.put(createdBy, innerMap);
Thanks #Tm Tron. The comment is working well. Im posting here the change for my preceders :
HashMap<MDocumentNumber, Integer> innerMap = new HashMap<MDocumentNumber, Integer>();
HashMap<Integer, HashMap<MDocumentNumber, Integer>> outerMap = new HashMap<Integer, HashMap<MDocumentNumber, Integer>>();
List<MDocumentNumber> docNumbers = new Query(getCtx(), MDocumentNumber.Table_Name, "IsActive = 'Y'", get_TrxName())
.setOrderBy("CreatedBy").list();
int createdBy = 0;
int nextUser = 0;
for (MDocumentNumber docNumber : docNumbers)
{
createdBy = docNumber.getCreatedBy();
MAttachment attachment = new MAttachment(getCtx(), MDocumentNumber.Table_ID, docNumber.get_ID(), get_TrxName());
int attchmentCount = attachment.getEntryCount();
int versionCount = docNumber.getVersionCount().intValue();
if(versionCount > 0 && attchmentCount < versionCount)
{
if(nextUser != 0 && nextUser != createdBy)
{
outerMap.put(nextUser, innerMap); // for a new user, put the inner map data to Outer Map
//innerMap.clear(); // Here while clearing the inner map, the outer map value is also clearing
innerMap = new HashMap<MDocumentNumber, Integer>();
}
innerMap.put(docNumber, (attchmentCount-versionCount));
nextUser = createdBy;
}
}
outerMap.put(createdBy, innerMap);
I am creating a table from ajax and the getting of values using a while loop:
while (rstdb.next()) {
rstdb.getInt(1)+"~"+ rstdb.getInt(2);
}
In my while loop my rstdb.getInt(1) will be 2,2,2,2,2,3,3...... and second values rstdb.getInt(2) are 10,20,30,40,50,10,20,.....
I need to sum up the values specific to 2 and values specific to 3 seperate.
ie,
It means 10+20+30+40+50 =150 for 2 and 10+20 =30 for 3.
It may contain single values also for example it may have 4,5,5,6,7,7....
How can I do that?
I need something like:
while (rstdb.next()) {
rstdb.getInt(1)+"~"+ rstdb.getInt(2)+"~"+sum;
}
The variable sum should contain the sum up value.
Use map for this. You can have a map which should be mapping the specific number with sum of it's corresponding value.
int c1, c2;
Map<Integer, Integer> sum = new HashMap<>();
while (rstdb.next()) {
c1 = rstdb.getInt(1);
c2 = rstdb.getInt(2);
if(sum.containsKey(c1)) {
sum.put(c1, sum.get(c1) + c2);
// ^ will return current sum of second column
} else {
sum.put(c1, c2);
}
rstdb.getInt(1)+"~"+ rstdb.getInt(2)+"~"+sum.get(c1);
}
You can use an integer to integer map:
Map<Integer, Integer> integerMap = new HashMap<>();
while (rstdb.next()) {
int column1 = rstdb.getInt(1);
int column2 = rstdb.getInt(2);
if (integerMap.containsKey(column1)) {
int currentSum = integerMap.get(column1);
integerMap.put(column1, currentSum + column2);
} else {
integerMap.put(column1, column2);
}
}
Edit: to print out the map, you can use loop through the entrySet of the map:
for (Map.Entry entry : integerMap.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
Does anyone know how to fix this ClassCastException error? I get:
"Exception in thread "main" java.lang.ClassCastException: java.util.HashMap$Entry cannot be cast to java.lang.Integer?
my problem is that I thought that I was calling the integer at that location, but apparently not? this assignment is due in 2 hours so ANY help is appreciated. Comments should tell whats going on.
public class WhyHellothere {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
process(s);
}
public static void process(Scanner s) {
HashMap hashmapofpricing = new HashMap();
HashMap hashmapofcount = new HashMap();
for (int i = 0; i < 1; i = 0) {
String itemDescription;
int count;
double unitPrice;
if ((itemDescription = s.next()).equals("end")) {
break;
}
count = s.nextInt();
Integer quantityValue;
if (hashmapofcount.get(itemDescription) != null) {
quantityValue = (Integer) hashmapofcount.get(itemDescription);
} else {
quantityValue = new Integer(0);
}
hashmapofcount.put(itemDescription, new Integer(new Integer(count).intValue()
+ quantityValue.intValue()));
unitPrice = s.nextDouble() * count;
Double costValue;
if (hashmapofpricing.get(itemDescription) != null) {
costValue = (Double) hashmapofpricing.get(itemDescription);
} else {
costValue = new Double(0);
}
hashmapofpricing.put(itemDescription, new Double(new Double(unitPrice).doubleValue()
+ costValue.doubleValue()));
}
Object itemdescription[] = hashmapofcount.entrySet().toArray();
Object howmanytimestheitemappears[] = hashmapofcount.entrySet().toArray();
int countIteration=0;
Object pricing[] = hashmapofpricing.entrySet().toArray();
int priceIteration=0;
Integer runningmaxamount = new Integer(0);
for (int i = 0; i < howmanytimestheitemappears.length; i++) {
int q = (Integer)howmanytimestheitemappears[i];//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<this is where the ClassCastException is. No idea why or how to fix.
if (q > runningmaxamount.intValue()) {runningmaxamount = q;countIteration = i;
}
}
Double maxcost = new Double(0);
for (int i = 0; i < pricing.length; i++) {
Double d = (Double) pricing[i];
if (d.doubleValue() > maxcost.doubleValue()) {
maxcost = d;
priceIteration = i;
}
}
String largestCountItem = (String) itemdescription[countIteration];
String largestCostItem = (String) itemdescription[priceIteration];
System.out.println("The largest count item with "
+ runningmaxamount.intValue() + " was: " + largestCountItem);
System.out.println("The largest total cost item at "
+ maxcost.doubleValue() + " was: " + largestCostItem);
}
}
First of all you have a problem with your HashMap declaration and initialization:
Its better to give what types you are storing in your hashmap like:
HashMap<String, Integer> hashmapofcount = new HashMap<String, Integer>();
Then you can traverse it easily with this kind of loop:
for (Map.Entry<String,Integer> entry : hashmapofcount.entrySet()) {
final String description = entry.getKey();
final Integer value = entry.getValue();
}
PS: And you don't need a lot of boxing the integer and doubles which makes your code look little terrible. Another thing you are adding two integers and doubles unitPrice and costValue, i think you might want to concatenate them by using unitPrice+" "+costValue(?)
Object howmanytimestheitemappears[] = hashmapofcount.entrySet().toArray();
for (int i = 0; i < howmanytimestheitemappears.length; i++) {
int q = (Integer)howmanytimestheitemappears[i];/
....
}
howmanytimestheitemappears[i] is of type HashMap$Entry. To get the key you need to call howmanytimestheitemappears[i].getKey()
Read http://docs.oracle.com/javase/7/docs/api/java/util/Map.Entry.html.
Please see the below code-
Map<DateTime, ArrayList<ElementInformationBean>> mapTithi = new HashMap<DateTime, ArrayList<ElementInformationBean>>();
List<ElementInformationBean> lstTime = null;
ElementInformationBean curntTithi = null;
ElementInformationBean nextTithi = null;
for (int i = 0; i < lstNakstra.size()-1; i++) {
lstTime = new ArrayList<ElementInformationBean>();
curntTithi = lstNakstra.get(i);
nextTithi = lstNakstra.get(i+1);
if(curntTithi.getStartTime().toDateMidnight().equals(nextTithi.getStartTime().toDateMidnight()))
{
lstTime.add(curntTithi);
lstTime.add(nextTithi);
mapTithi.put(curntTithi.getStartTime().toDateMidnight().toDateTime(), (ArrayList<ElementInformationBean>) lstTime);
} else {
lstTime.add(curntTithi);
mapTithi.put(curntTithi.getStartTime().toDateMidnight().toDateTime(), (ArrayList<ElementInformationBean>) lstTime);
}
}
For Printing
for (Map.Entry<DateTime, ArrayList<PanchangaElementInformationBean>> entry : mapTithi.entrySet()) {
DateTime key = entry.getKey();
ArrayList<PanchangaElementInformationBean> values = entry.getValue();
System.out.println("Key = " + key);
for (PanchangaElementInformationBean p: values) {
System.out.print("Values = " + p.getStartTime() + "n");
}
}
I am trying to use the HashMap; Key as dateTime and Value as List. However it always returns when I am iterating and printing the value.
Thanks
Kumar Shorav
Initialize lstTime outside the loop.
Try this code :
Map<DateTime, ArrayList<ElementInformationBean>> mapTithi = new HashMap<DateTime, ArrayList<ElementInformationBean>>();
// Intialize here
List<ElementInformationBean> lstTime = new ArrayList<ElementInformationBean>();
ElementInformationBean curntTithi = null;
ElementInformationBean nextTithi = null;
for (int i = 0; i < lstNakstra.size()-1; i++) {
curntTithi = lstNakstra.get(i);
nextTithi = lstNakstra.get(i+1);
if(curntTithi.getStartTime().toDateMidnight().equals(nextTithi.getStartTime().toDateMidnight()))
{
lstTime.add(curntTithi);
lstTime.add(nextTithi);
mapTithi.put(curntTithi.getStartTime().toDateMidnight().toDateTime(), (ArrayList<ElementInformationBean>) lstTime);
} else {
lstTime.add(curntTithi);
mapTithi.put(curntTithi.getStartTime().toDateMidnight().toDateTime(), (ArrayList<ElementInformationBean>) lstTime);
}
}
On your Getters and Setters of the PanchangaElementInformationBean class change the data type from Date to ArrayList<Date> and add that setStartTime to as bellow so you can get all values from it.
private ArrayList<Date> startTime;
public ArrayList<Date> getStartTime() {
return startTime;
}
public void setStartTime(Date item) {
if (startTime == null) {
startTime = new ArrayList<Date>();
}
this.startTime.add(item);
}
So while you iterate you can get all the values from the ArrayList
And add this on the main printing for loop to print individual Date from ArrayList
for (Date startTime : p.getStartTime()) {
System.out.println(startTime);
}
And Initialize lstTime = new ArrayList<ElementInformationBean>(); on above the For Loop so that you can add many elements are else it will add only one for loop instance value repeatedly to the list.
If you want to accumulate elements in a list used as value of a map, you have to use this approach:
List<...> list = map.get( key );
if( null == list ) {
list = new ...;
map.put( key, list );
}
list.add( ... );
I'm having some trouble sorting out this code, which is in a hashmap - I also need some help sorting out a similar code set for a double (price). Thank You.
#SuppressWarnings("unused")
public class Inventory {
Scanner in = new Scanner(System.in);
ArrayList<Sellable> groceries;
HashMap<String, Integer> stock;
public Inventory() {
groceries = new ArrayList<Sellable>();
stock = new HashMap<String, Integer>();
//HARDCODING...:
Sellable n1 = new Produce("Corn", 3, 5.00);
Sellable n2 = new Snack("Natural Popcorn Seeds", 2.50);
Sellable n3 = new Produce("Potatoes", 3, 5.00);
Sellable n4 = new Snack("Organic Potato Chips", 2.50);
Sellable n5 = new Produce("Apples", 5, 1.75);
Sellable n6 = new Snack("Apple Juice - 128 oz.", 3.50);
Sellable n7 = new Produce("Oranges", 5, 1.75);
Sellable n8 = new Snack("Orange Juice - 128 oz.", 3.50);
//ADD TO HASHMAP
groceries.add(n1);
groceries.add(n2);
groceries.add(n3);
groceries.add(n4);
groceries.add(n5);
groceries.add(n6);
groceries.add(n7);
groceries.add(n8);
//PUT UP FOR PRINTING
stock.put(n1.getName(), 50);
stock.put(n2.getName(), 100);
stock.put(n3.getName(), 50);
stock.put(n4.getName(), 100);
stock.put(n5.getName(), 50);
stock.put(n6.getName(), 100);
stock.put(n7.getName(), 50);
stock.put(n8.getName(), 100);
}
//Sorting Method 1
#SuppressWarnings("unchecked")
public void sortByName() {
groceries = new ArrayList<Sellable>();
stock = new HashMap<String, Integer>();
{
if (stock != null) {
List<Sellable> groceries = new ArrayList<Sellable>();
stock.addAll(((Entry<String, Integer>) stock).getValue(), groceries);
Collections.sort(groceries, new Comparator<Sellable>() {
public int compare(Sellable product1, Sellable product2) {
try {
Sellable choice1 = (Sellable) product1;
Sellable choice2 = (Sellable) product2;
//LESS THAN
if (choice1.getName().compareTo(choice2.getName()) < 0) {
return -1;
} //GREATER THAN
else if (choice1.getName().compareTo(choice2.getName()) > 0) {
return 1;
} //EQUALS
else {
return 0;
}
} catch (ClassCastException FAIL) {
return -2;
}
}
});
}
}
}
}
Please remove the lines of code,
groceries = new ArrayList<Sellable>();
stock = new HashMap<String, Integer>();
from your mehod sortByName().
This lines reset the groceries and stock to empty.
Sorry, but neither your code or your Question makes a lot of sense to me.
Your sortByName is clobbering both groceries and stock.
Then it is apparently attempting to copy from the (now) empty HashMap to the ArrayList. But it is nonsensical because
you are attempting to use a non-existent method (HashMap.addAll),
you are casting a HashMap to an Entry,
and so on.
The Comparator looks plausible for sorting "by name", but your code that returns -2 in the event of a ClassCastException is wrong. You should just let the exception propagate ... if it arises. You don't actually do a type-cast in the Comparator. The arguments have the correct type. (Casting a Sellable to a Sellable? Why ???)
Thought of adding a new answer instead of editing my previous answer.
Please note that you should not (re)initialize the member variables in methods unless it is really required. Also I have used String.compareTo() to compare names.
Please find below the modified sort method:
#SuppressWarnings("unchecked")
public void sortByName() {
// groceries = new ArrayList<Sellable>();
// stock = new HashMap<String, Integer>();
if (stock != null) {
//List<Sellable> groceries = new ArrayList<Sellable>();
//stock.addAll(((Entry<String, Integer>) stock).getValue(), groceries);
Collections.sort(groceries, new Comparator<Sellable>() {
public int compare(Sellable product1, Sellable product2) {
try {
return product1.getName().compareTo(product2.getName());
} catch (Exception FAIL) {
return -2;
}
}
});
}
}
}