【问题标题】:Initializing 2D ArrayList for for-loop summation (Java)为 for 循环求和初始化 2D ArrayList (Java)
【发布时间】:2018-10-15 11:03:51
【问题描述】:

我正在尝试对 N 对整数(一个 Nx2 ArrayList)求和,并将 N 个总和作为 ArrayList 返回。虽然我知道没有必要设置一个班级来完成这个,但我想这样做作为未来项目的练习。

import java.util.ArrayList;

public class SumsInLoop {
    public SumsInLoop(int numberOfPairs, ArrayList<ArrayList<Integer>> numbersList) {}

    public ArrayList<Integer> getSums(int numberOfPairs, ArrayList<ArrayList<Integer>> numbersList) {
        ArrayList<Integer> pairsOfSums = new ArrayList<Integer>();
        for (ArrayList<Integer> Pair : numbersList) {
            int x = Pair.get(0);
            int y = Pair.get(1);
            int sum = x + y;
            pairsOfSums.add(sum);
        }
        System.out.println(pairsOfSums);
        return pairsOfSums;
    }

我得到的数据是 N 对(numbersOfPairs)整数的随机分类,例如612673 108695。我想将这些整数对添加到将由 getSums 调用的 2D ArrayList (numbersList)。

但是,我在初始化 numbersList 时遇到了困难。我的主要功能如下:

    public static void main(String[] args) {
        int myNumberOfPairs = 13;
        ArrayList[][] myNumbersList = new ArrayList[13][2];
        myNumbersList[0][0] = new ArrayList<>();
        myNumbersList[0][0].add(612673);
        myNumbersList[0][1].add(108695);
        myNumbersList[1][0] = new ArrayList<>();
        myNumbersList[1][0].add(756875);
        myNumbersList[1][1].add(496058);
        SumsInLoop mySum = new SumsInLoop(myNumberOfPairs,myNumbersList);
        mySum.getSums(myNumberOfPairs, myNumbersList);

最后两行代码抛出错误,要求我将 myNumbersList 更改为类型 ArrayList&lt;List&lt;Integer&gt;&gt;,这会引发更多错误,即使在将所有 2D ArrayLists 更改为类型 ArrayList&lt;List&lt;Integer&gt;&gt; 之后也是如此。

所以,我的两个问题如下:

  1. 如何初始化 NxM ArrayList 并正确填充它?
  2. 是否有更快的方法来完成这项任务,同时仍然使用类方法?

附:我习惯使用 Python 进行编码,并且正在自学 Java,因此非常感谢您提供给我的任何其他信息或资源。

【问题讨论】:

  • 您有什么理由要使用ArrayList 而不是普通数组吗?
  • 我还能在普通数组中指定参数吗?如果是这样,那么没有。
  • 您可能想要查看的内容(可能更适合您想要做的事情)是创建一个仅存储两个值的 Pair 类,然后让您的函数接受一个Pairs 的数组,即 Pair[]

标签: java arrays for-loop arraylist


【解决方案1】:

您可能希望通过使用int 的二维数组来简化输入:int[][] myNumbersList = new int[13][2];
在这种情况下,预期的输出是int[13] 的一维数组,可以按如下方式获得(用 2 对演示。参见mcve):

public class SumsInLoop {
    //pairsOfInts should be an [n][2] array
    private static int[] sumOfPairs(int[][] pairsOfInts) {

        int[] sums = new int[pairsOfInts.length];
        for(int pairIndex = 0; pairIndex < pairsOfInts.length; pairIndex++) {
            sums[pairIndex]= pairsOfInts[pairIndex][0]+pairsOfInts[pairIndex][1];
        }
        return sums;
    }

    public static void main(String[] args) {
        int numberOfPairs = 2;
        int[][] pairsOfInts = new int[numberOfPairs][2];
        pairsOfInts[0] = new int[] {612673,108695 };
        pairsOfInts[1] = new int[] {756875,496058 };
        int[] sumOfPairs = sumOfPairs(pairsOfInts);
        System.out.println(Arrays.toString(sumOfPairs));
    }
}

如果您想要使用 List 实现的解决方案,您可以使用 javafx Pair(或创建您自己的 pair 类。
输入可以定义为List&lt;Pair&lt;Integer,Integer&gt;&gt; pairsOfInts = new ArrayList&lt;&gt;();
输出可以是上面的数组,也可以是List&lt;Integer&gt;

import java.util.ArrayList;
import java.util.List;
import javafx.util.Pair;

public class SumsInLoop {

    private static List<Integer> sumOfPairs(List<Pair<Integer, Integer>> pairsOfInts) {
        List<Integer> sums = new ArrayList<>();
        for(Pair<Integer,Integer> pair : pairsOfInts) {
            sums.add(pair.getKey()+ pair.getValue());
        }
        return sums;
    }

    public static void main(String[] args) {
        List<Pair<Integer,Integer>> pairsOfInts = new ArrayList<>();
        pairsOfInts.add (new Pair<>(612673,108695 ));
        pairsOfInts.add (new Pair<>(756875,496058));
        List<Integer> sumOfPairs = sumOfPairs(pairsOfInts);
        System.out.println(sumOfPairs); 
    }
}

【讨论】:

    【解决方案2】:

    您得到的(编译)异常是由于您期望ArrayList&lt;ArrayList&lt;Integer&gt;&gt;,但传递了ArrayList[][]。 (在Java中不一样)

    1. 在您的情况下,您需要(在 main 方法中):

      ArrayList<ArrayList<Integer>> myNumbersList = new ArrayList</* when java > 6 ;)*/>(13);
      

      这仅设置(父)列表的容量(..和底层/内部支持数组) 初始化子列表,你不会来循环(不知何故......甚至不是在 python 中:):

      for (int i = 0; i < 13; i++) {
          myNumbersList.add(new ArrayList<Integer>(2));
      }
      

      取决于“正确”的含义......但我假设使用“随机数据”,理想情况下你会再次内部循环:

      java.util.Random rnd = new Random(/*seed default current timestamp*/);
      //...
      for (int i = 0; i < 13; i++) {
        ArrayList<Integer> innerList = new ArrayList<>(2);
        for (int j = 0; j < 2; j++) {
          innerList.add(rnd.netxInt(/*bound default Integer.MAX_VALUE*/) /*+/-/% offset*/);
        }
        myNumberList.add(innerList);
      }
      
    2. 抱歉,我不知道有一种(更快的方式),但很大程度上取决于“输入格式”。

    【讨论】:

      【解决方案3】:

      由于您已经知道一对中值的数量,因此不需要ArrayList。您可以创建自己的、更简单的一对实现。

      class Pair {
          public final int left;
          public final int right;
      
          public Pair(int left, int right){
              this.left = left;
              this.right = right;
          }
      }
      

      然后您可以通过创建对对象并访问其字段来访问这些值。

      Pair p = new Pair(10, 7);
      System.out.println(p.left); // 10
      System.out.println(p.right); // 7
      

      然后您可以更轻松地重新定义您的 getSums 方法。

      public static List<Integer> getSums(List<Pair> pairs){
          List<Integer> pairsOfSums = new ArrayList<>();
          for(Pair pair : pairs){
              int sum = pair.left + pair.right;
              pairsOfSums.add(sum);
          }
          return pairsOfSums;
      }
      

      请注意函数可以是static,你不需要传递对的数量。 for-each 循环将循环遍历所有这些。


      然后初始化数组比您在问题中描述的方法更容易。

      List<Pair> pairs = new ArrayList<>();
      pairs.add(new Pair(7, 10));
      pairs.add(new Pair(18, 3));
      pairs.add(new Pair(-6, 0));
      pairs.add(new Pair(4, 2));
      System.out.println(SumsInLoop.getSums(pairs));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-28
        • 1970-01-01
        • 2011-04-02
        • 1970-01-01
        • 2013-09-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多