【问题标题】:Iterating over an ArrayList adding values遍历 ArrayList 添加值
【发布时间】:2015-11-16 17:29:59
【问题描述】:

是否可以迭代一个 ArrayList,而不是添加所有实例,而是每 12 个?使用 addAll 添加所有实例但不添加部分有很多线程。

我目前有一个包含数百个浮点值的 ArrayList:

片段:

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, ...

我想要做的是将前 12 个实例相加并将其放入一个新的 ArrayList 中,将接下来的 12 个实例相加,将其存储到新创建的 ArrayList 中,依此类推。正好有 996 个实例,所以我应该在这个新的 ArrayList (996/12=83) 中有 83 个新值。

这可以吗?如果有怎么办?这是我要去的地方...

  // 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)
  {
    ??????????????????
  }
  }

任何帮助将不胜感激我似乎无法在任何地方找到任何关于此的内容,因为我认为所有实例的总和是如此受欢迎的话题。它可能是正确迭代的情况。关于求和,我会在 c++ 中使用 accumulate,但不知道 java 中的等价物(如果有的话)。感谢您提前提供任何建议/帮助!

更多代码:

public class WeatherStation {
  private ArrayList<MonthData> months;
  private ArrayList<MonthData> rValue;
  private ArrayList<MonthData> depthAdd;

MonthData 是一个用于将数据读取到此类的模型,它由许多 getter 组成....

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;

}

推荐代码:

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

问题:Iterator&lt;Float&gt; it = rValue.iterator();

类型不匹配:无法从 Iterator&lt;MonthData&gt; 转换为 Iterator&lt;Float&gt;

【问题讨论】:

    标签: java for-loop arraylist floating-point iteration


    【解决方案1】:

    执行此操作的最佳方法是使用Iterator12 的计数器,即使用while。这是一个例子:

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

    【讨论】:

    • counter &lt;= MAX 应该是您使用1 启动计数器时的条件。
    • 非常感谢您!但是我确实有一个问题:Iterator&lt;Float&gt; it = rValue.iterator(); Type mismatch: cannot convert from Iterator to Iterator
    • @Abbie 那是什么问题?您能否在编辑问题后提供更多代码以提供适当的帮助?
    • @Abbie 来自您的新代码,您已经定义了ArrayList&lt;MonthData&gt; rValue,并且在之前的代码中您使用的是ArrayList&lt;Float&gt; rValue。如果您使用的是前者,请将您的迭代器更改为Iterator&lt;MonthData&gt; it,而不是使用sum += it.next() 使用sum += it.next().&lt;nameOfYourGetter&gt;();
    • 我为你添加了一张图片。认为这里混淆了,rValue 是&lt;Float&gt;,因此我不明白我得到的错误:(
    【解决方案2】:

    我建议您使用 doubleDouble 而不是 float,因为它的准确度大约是 0.5 万亿倍。

    你可以像这样对每个 12 块求和

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

    然后打电话

    List<Double> sums = sumBlocks(list, 12);
    

    【讨论】:

    • Math.min 有一个参数?
    • 您不能使用double 或任何带有泛型的原始类型,它必须是对象类型。
    • @abhishekbafna 确实,但有些库的集合支持原语。 koloboke、trove、gs-collections 等。java-performance.info/…
    • @abhishekbafna 他没有将double 与泛型一起使用。我没有看到问题。 (如果你说的是sum,这是合法的;Java 会在必要时自动在Doubledouble 之间转换。)
    【解决方案3】:

    只是为了演示另一种实现此目的的方法:

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

    【讨论】:

      【解决方案4】:
      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;
      

      【讨论】:

        【解决方案5】:

        试试这个:

        public float total;
        
        for(int i; i < rValue.Size(); i ++)
        {
             total += rValue[i];
        
        if(i%12=0)
          {
             add total to new ArrayList
             total = 0;
          }
        }
        

        【讨论】:

          【解决方案6】:

          Arraylist 对象从 List 类继承 sublist(start, end) 方法。您可以使用 myList.sublist(i, j) 访问子列表并获取总和。从那里,它应该只是简单的算术来获得你的迭代。在你的 for 循环中,它应该是: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;
              }
          

          在列表中添加项目的辅助方法

          static float listSum(List<Float> ar) {
              float accumulator = 0f;
              for(float item:ar) {
                  accumulator += item;
              }
              return accumulator;
          }
          

          【讨论】:

            猜你喜欢
            • 2013-03-09
            • 2012-11-19
            • 2015-11-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-02-10
            • 1970-01-01
            • 2019-01-25
            相关资源
            最近更新 更多