1

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?

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Wish
  • 1,594
  • 1
  • 18
  • 36
  • 2
    What have you done so far? Any specific problem you need help with? – Jacob May 30 '11 at 07:32
  • not much... actually this data is from sqlite database. positive values is in one table, negative values is from other table. Maybe it is possible with sql querys, but i dont understand sql that much,thoght that with arraylist it will be easier to do? – Wish May 30 '11 at 07:38
  • Really, do it in SQL. Please. – Waldheinz May 30 '11 at 08:36

4 Answers4

8

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());
Community
  • 1
  • 1
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • @Sean: I admit: I'm working hard to get that established as a accepted term ;-) When I can link to a third-party source instead of my own answer, then I'll have won. – Joachim Sauer May 30 '11 at 08:26
2

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.

slothrop
  • 3,218
  • 1
  • 18
  • 11
1
  • use a 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

  • Iterate through ArrayList
  • Check if the Date exist in the Map, Update the entry , add otherwise
jmj
  • 237,923
  • 42
  • 401
  • 438
1

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());
    }

}
Nikhil Agrawal
  • 26,128
  • 21
  • 90
  • 126
Shilaghae
  • 957
  • 12
  • 22