Reputation: 1614
I have an ArrayList
of String[]
.
Each String[]
contains two values: value and date.
If I print it, it will look something like this:
value | date -------|---------- 357.0 | 2011/05/30 -234.0 | 2011/05/31 -123.0 | 2011/05/30
i want to make a new ArrayList
, where all values in same date are summed. Like this:
value | date -------|---------- 234.0 | 2011/05/30 -234.0 | 2011/05/31
Can anyone help?
Upvotes: 1
Views: 883
Reputation: 957
You could use HashMap with the date as key!
Something simple:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
public class Sum {
/**
* @param args
*/
private ArrayList < String[] > date;
private HashMap < String, Double > date_hash;
public Sum() {
date = new ArrayList < String[] > ();
date.add(new String[] {
"357.0", "2011/05/30"
});
date.add(new String[] {
"-234.0", "2011/05/31"
});
date.add(new String[] {
"-123.0", "2011/05/30"
});
}
public static void main(String[] args) {
new Sum().sum();
}
public void sum() {
date_hash = new HashMap < String, Double > ();
for (int i = 0; i < date.size(); i++) {
String[] array = date.get(i);
String key = array[1];
if (date_hash.containsKey(key)) {
date_hash.put(key, Double.valueOf(array[0]) + Double.valueOf(date_hash.get(key)));
} else {
date_hash.put(key, Double.valueOf(array[0]));
}
}
Set < Entry < String, Double >> set = date_hash.entrySet();
Iterator < Entry < String, Double >> iterator = set.iterator();
while (iterator.hasNext())
System.out.println(iterator.next());
}
}
Upvotes: 1
Reputation: 308021
You too, are suffering from object denial.
String
is not a good type for handling numbers or dates. For a number I'd use int
(if you only have integer values), double
or BigDecimal
(if it's a monetary ammount or some other exact decimal number).
For the date I'd use either a Date
/Calendar
or LocalDate
from Joda Time (if you can use an external library).
Obviously this means that you can no longer store your data in a String[]
, but that's not really an appropriate type for any kind of structured data, anyway.
You'd want to write a class that reflects what your values are about:
public class DatedValue {
private final Date date;
private final BigDecimal value;
public DatedValue(final Date date, final BigDecimal value) {
this.date = date;
this.value = value;
}
public Date getDate() {
return date;
}
public BigDecimal getValue() {
return value;
}
}
Then you can simply create the new values by iterating over the original ArrayList<DatedValue>
:
Map<Date,DatedValue> result = new LinkedHashMap<Date,DatedValue>();
for(DatedValue dv : datedValues) {
DatedValue newDV = result.get(dv.getDate());
if (newDV == null) {
newDV = dv;
} else {
newDV = new DatedValue(dv.getDate(), dv.getValue().add(newDV.getValue()));
}
result.put(dv.getDate(), newDV);
}
List<DatedValue> sums = new ArrayList<DatedValue>(result.values());
Upvotes: 8
Reputation: 5418
If you prefer to do it at the SQL layer, you can do something like this:
SELECT date, SUM(value)
FROM
(SELECT date, value
FROM positive_values_table
UNION ALL
SELECT date, value
FROM negative_values_table)
GROUP BY date
Not that you can't do it in Java, but this kind of aggregation is bread and butter for SQL.
Upvotes: 2
Reputation: 240870
Map<Date, Double> dateToValueMap
Note: You can either use String as key (Date in the form of String) , Or you can make use of SimpleDateFormat
class to get Date
from String
ArrayList
Upvotes: 1