Reputation: 153
Is it possible to iterate over a ArrayList adding not all instances but every 12? There are many threads on using addAll to add all instances but not sections.
I currently have an ArrayList containing hundreds of float values:
Snippet:
120.5, 22.2, 76.2, 64.5, 38.3, 27.1, 149.4, 62.3, 127.9, 79.1, 83.4, 68.3, 61.0, 83.4, 5.4, 83.8, 78.3, 111.8, 104.1, 145.2, 94.3, 20.0, 104.7, 35.9, 68.6, 10.1, 41.1, 82.2, 170.7, 17.2, 122.1, 61.0, 46.3, 101.1, 59.0, 30.0, ...
What I want to do is sum the first 12 instances and put this total in a new ArrayList, sum the next 12 instances, store this into the newly created ArrayList and so on. There are exactly 996 instances so i should have 83 new values in this new ArrayList (996/12=83).
Can this be done? If so how? Here is where I have got to...
// ArrayList that contains the float values shown above
public MonthData depthValues() {
ArrayList<Float> rValue = new ArrayList<>();
for (int i = 0; i<months.size(); i++)
{
rValue.add(months.get(i).getDepthMM());
}
System.out.println(rValue);
System.out.println(rValue.size());
return null;
}
//New arrayList im trying to make
//probably done this wrong, help needed here
public MonthData depthTotals() {
ArrayList<Float> depthAdd = new ArrayList<Float>();
int t = 12;
for(int i = 0; i<rValue.size(); ++i)
{
??????????????????
}
}
Any help will be greatly appreciated I cant seem to find anything on this anywhere as I think the sum of all instances is such a popular topic. Its probably a case of iterating properly. In regards to the summing I would have use accumulate
in c++, but do not know the equivalent of this in java (if there is one). Thank you for any advice/assistance in advance!
MORE CODE:
public class WeatherStation {
private ArrayList<MonthData> months;
private ArrayList<MonthData> rValue;
private ArrayList<MonthData> depthAdd;
MonthData is a model for data being read to this class it consists on a lot of getters....
public class MonthData {
int y;
int m;
float h;
...
public MonthData(String data) throws Exception {
...
this.parseData(data);
}
void parseData(String csvData) {
String[] parseResult = csvData.trim().split("\\s+");
this.setYear(parseResult[0]);
this.setMonth(parseResult[1]);
...
public String toString() {
return "y =" + year + ", m =" + month + ",...
}
public int getY() {
return y;
}
// followed by lots of getters for: m, h, c, f, r, s, ...
public MonthData depthValues() {
ArrayList<Float> rValue = new ArrayList<>();
for (int i = 0; i<months.size(); i++)
{
rValue.add(months.get(i).getDepthMM());
}
System.out.println(rValue);
System.out.println(rValue.size());
return null;
}
Code recommended:
public MonthData depthTotals() {
ArrayList<Float> depthAdd = new ArrayList<>();
Iterator<Float> it = rValue.iterator();
final int MAX = 12;
while (it.hasNext()){
float sum = 0f;
int counter = 1;
//iterating 12 times
//still check if there is an element in list
while (counter < MAX && it.hasNext()){
sum += it.next();
counter++;
}
depthAdd.add(sum);}
}
ISSUE: Iterator<Float> it = rValue.iterator();
Type mismatch: cannot convert from Iterator<MonthData>
to Iterator<Float>
Upvotes: 1
Views: 3946
Reputation: 758
Arraylist objects inherit the sublist(start, end) method from the List class. You can use myList.sublist(i, j) to access the sublist and get your sum. From there, it should be just simple arithmetic to get your iteration. Inside your for-loop, it should be: myList.sublist(i*12, i*12 + 12).
//Input list
ArrayList<Float> inputList = new ArrayList<Float>();
ArrayList<Float> result = new ArrayList<Float>();
int groupSize = 12;
int offset=0;
while(offset < inputList.size()) {
int toIndex = (inputList.size()-offset)>=groupSize? offset+groupSize : inputList.size();
result.add( listSum(inputList.subList(offset, toIndex)) );
offset += groupSize;
}
Helper method to add items in a list
static float listSum(List<Float> ar) {
float accumulator = 0f;
for(float item:ar) {
accumulator += item;
}
return accumulator;
}
Upvotes: 0
Reputation: 114
try this:
public float total;
for(int i; i < rValue.Size(); i ++)
{
total += rValue[i];
if(i%12=0)
{
add total to new ArrayList
total = 0;
}
}
Upvotes: 0
Reputation: 592
Lista<Double> list = // original list
List<Double> ret = new ArrayList<>();
int counter = 0;
double sum = 0;
for (Double f : list) {
if (counter == 12) {
sum = 0;
counter = 0;
ret.add(sum);
}
sum += f;
counter++;
}
// if list is not a multiple of 12
if (list.size() % 12 != 0) {
ret.add(sum);
}
return ret;
Upvotes: 0
Reputation: 31699
Just to demonstrate yet another way to accomplish this:
public static List<Double> sumBlocks(List<Double> list, int blockSize) {
List<Double> result = new ArrayList<>();
double sum = 0d;
for (int i = 0; i < list.size(); i++) {
if (i > 0 && i % blockSize == 0) {
result.add(sum);
sum = 0d;
}
sum += list.get(i);
}
result.add(sum);
return result;
}
Upvotes: 2
Reputation: 533790
I would recommend you use double
or Double
instead of float as it has around half a trillion times the accuracy.
You can sum every block of 12 like this
public static List<Double> sumBlocks(List<Double> list, int blockSize) {
List<Double> ret = new ArrayList<>();
for(int i = 0; i < list.size(); i += blockSize) {
double sum = 0;
for(int j = 0, len = Math.min(list.size() - i, blockSize); j < len; j++)
sum += list.get(i + j);
ret.add(sum);
}
return ret;
}
and call
List<Double> sums = sumBlocks(list, 12);
Upvotes: 3
Reputation: 85789
The best way to do this is using Iterator
and a counter of 12
by using a while
. Here's an example:
List<Float> yourList = ...;
// fill yourList
List<Float> results = new ArrayList<>();
Iterator<Float> it = yourList.iterator();
final int MAX = 12;
while (it.hasNext()) {
float sum = 0f;
int counter = 1;
//iterating 12 times
//still, check if there's an element in your list
while (counter <= MAX && it.hasNext()) {
sum += it.next();
counter++;
}
result.add(sum);
}
Upvotes: 3