简体   繁体   中英

Iterating over an ArrayList adding values

在此处输入图片说明 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>

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

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

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM