Java: 访问多维数组中一行的元素?

Java: Accessing elements of a row in a multidimensional array?

我正在做一个 Java 项目并构建了一个这样的多边形:

DPolygons[NumberOf3DPolygons] = new DPolygon(new double[]{0, 2, 2, 0}, new double[]{0, 0, 0, 0},  new double[]{0, 0, 3, 3}, Color.red);

而 class DPolygon 具有以下构造函数:

public DPolygon(double[] x, double[] y, double[] z, Color c)
{
    Screen.NumberOf3DPolygons++;
    this.x = x;
    this.y = y;
    this.z = z;
    this.c = c;
    createPolygon();
}

我想做的是计算其 z 坐标的总和(在本例中为 = 6) 这是我的想法:

sum = DPolygons[NumberOf3DPolygons].z[0]+DPolygons[NumberOf3DPolygons].z[1]+
                    DPolygons[NumberOf3DPolygons].z[2]+DPolygons[NumberOf3DPolygons].z[3];

但它给出了 NullPointerException,因为它无法将 DPolygons[NumberOf3DPolygons].z[0] 识别为多边形的第一个 z 值,依此类推。

谁能告诉我访问每个 z 元素的正确语法是什么? (或者我怎样才能得到这笔钱?)

  for(int i=0; i<DPolygons.length; i++){
        //If you have some condition, you can put over here.
        if(condition) {
        sum = DPolygons[i].z + sum; 
        }

    }

全局变量z是否声明public?

public double z;

但是,我建议在 Dpolygon class 中创建一个 public 方法来检索全局 z 值并使用该 getter 而不是直接调用 属性。

里面class:

public Double [ ] getZ (){return new Double (z[1],z [2],z [3]);}

这样设计 class...

public class DPolygon
{
    private double[] x, y, z;
    private Color color;

    public DPolygon(double[] x, double[] y, double[] z, Color color)
    {
        // Number of polygons best found in containing class.
        this.x = x;
        this.y = y;
        this.z = z;
        this.color = Color;
    }

    public double[] getZ()
    {
        return z;
    }

    //...Other getters and setters.
}

使用带有嵌套 foreach 循环的 ArrayList 获取所有多边形的所有 z 值...

ArrayList<DPolygon> dPolygons = new ArrayList<DPolygon>();

dPolygons.add(new DPolygon(new double[]{0, 2, 2, 3}, new double[]{0, 0, 0, 0},  new double[]{0, 0, 3, 3},Color.Red));

double sum=0;
for(DPolygon polygon : dPolygons)
{
    for (double zValue : polygon.getZ())
    {
        sum += zValue;
    }
}

对于特定的多边形...

double sum2 = 0;
//Change index number to whatever specific polygon you want to sum.
int specificPolygon=0;
// Then to sum.
for(double zValue : dPolygons.get(specificPolygon).getZ())
{
    sum2 += zValue;
}

但是如果你嫁给了一个数组...

DPolygons[] dPolygons = new DPolygons[numberOfPolygons];

dPolygons[0] = new DPolygon(new double[]{0, 2, 2, 3}, new double[]{0, 0, 0, 0},  new double[]{0, 0, 3, 3},Color.Red)
//...Adding other polygons

// For single polygon
double sum3 = 0;
// As before, set specificPolygon equal to the index of the polygon you want.
int specificPolygon = 0;
for(double zValue : dPolygons[specificPolygon].getZ())
{
    sum3 += zValue;
}

最后一种方法的问题是你需要知道数组初始化时屏幕上多边形的数量。您不能在运行时动态添加更多内容。

What I want to do is to calculate the sum of its z coordinates (which in this case will be = 6)

如果我是你,我会为 z 的总和(甚至是 x 和 y 的总和)创建一个方法:

class DPolygon
{
    private double[] z;
    //Your other attributes here..
    //Your constructors here..

    public double getSumOfZ(){
        double sum = 0.0;
        if(z != null && z.length > 0)
            for(int i=0; i<z.length; i++)
                sum += z[i];
        return sum; 
    }
}

例如,如果您有一组 3D 多边形:

//Outside the class (for e.g. from the main method):
DPolygon poly1 = new DPolygon(new double[]{0, 2, 2, 0}, new double[]{0, 0, 0, 0},  new double[]{0, 0, 3, 3}, Color.red)};
DPolygon poly2 = new DPolygon(new double[]{0, 2, 2, 0}, new double[]{0, 0, 0, 0},  new double[]{0, 0, 3, 3}, Color.red)};
DPolygon poly3 = new DPolygon(new double[]{0, 2, 2, 0}, new double[]{0, 0, 0, 0},  new double[]{0, 0, 3, 3}, Color.red)};

DPolygons[NumberOf3DPolygons] polygons3D = {poly1, poly2, poly3};

要访问特定 3D 多边形的 z 总和:

polygons3D[0].getSumOfZ();   //Get sum of z from first polygon

But it gives a NullPointerException because it doesn't recognize DPolygons[NumberOf3DPolygons].z[0] as the first z value of the polygon and so on.

在您的情况下 NullPointerException 有 2 种可能性:

  1. 您没有在 DPolygon 中初始化 z 数组 class。
  2. 您正在使用的数组中的 DPolygon 元素为空。

确保从 DPolygon class:

初始化 z array
class DPolygon
{
    //Your other attributes here..
    private double[] x,y,z;
    public DPolygon(){
        initCoordinates();    //Init all arrays in the constructor 
    }

    //Initialize all x,y,z arrays.
    private void initCoordinates(){
        x = new double[]{0.0, 0.0, 0.0, 0.0};
        y = new double[]{0.0, 0.0, 0.0, 0.0};
        z = new double[]{0.0, 0.0, 0.0, 0.0};
    }
}

关于这个主题还有两个简洁的概念要介绍:Collections and, new in Java 1.8, Reduction of Streams

使用 List 将消除因尝试使用全局变量管理动态数组而导致的 NullPointerExceptions。 在您的情况下,在 DPolygon 的构造函数中递增 Screen.NumberOf3DPolygons 不是正确的位置。如果您构造另一个 DPolygon 而不将其添加到该数组中,会发生什么情况?您可能希望在管理数组的对象中使用 add 方法,使该变量与添加到列表中的元素数量一致。幸运的是,这已经在 Java 集合 classes.

中为我们完成了

这是演示使用 Collections 的相关代码的工作复制品,还有另一个好东西:用于计算 z 坐标总和的单行代码。

import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main1
{
    public static class Screen
    {
        List<DPolygon> polygons = new ArrayList<>();
    }

    public static class DPolygon
    {
        private double[] x, y, z;

        private Color c;

        public DPolygon( double[] x, double[] y, double[] z, Color c )
        {
            this.x = x;
            this.y = y;
            this.z = z;
            this.c = c;
        }

        public double sumZ()
        {
            return Arrays.stream( z ).sum();
        }

    }

    public static void main( String[] args )
    {
        Screen screen = new Screen();

        screen.polygons.add(
            new DPolygon(
                new double[] { 0, 2, 2, 0 },
                new double[] { 0, 0, 0, 0 },
                new double[] { 0, 0, 3, 3 },
                Color.red ) );

        System.out.println( screen.polygons.get( 0 ).sumZ() );
    }
}

当您尝试对特定索引使用 xyz 中的至少两个时,仍然有可能出现 IndexOutOfBoundsException:我们不确定每个点都有 3 个坐标,因为一些数组可能比另一个小。为了确保所有点都有 3 个坐标,您可以像这样对它们进行分组:

       screen.polygons.add(
            new Polygon(
                Color.RED,
                new double[] { 0, 0, 0 },
                new double[] { 2, 0, 0 },
                new double[] { 2, 0, 3 },
                new double[] { 0, 0, 3 } ) );

使用这个 DPolygon class:

    public static class DPolygon
    {
        List<double[]> points = new ArrayList<>();

        Color color;

        public DPolygon( Color c, double[]... coords )
        {
            this.points = Arrays.asList( coords );
            this.color = c;
        }

        public double sumZ()
        {
            return points.stream().mapToDouble( ( p ) -> p[2] ).sum();
        }
    }

你可以走得更远,把这个点抽象成一个

    public static class Point3D
    {
        double x, y, z;

        public Point3D( double x, double y, double z )
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }
    }

double[] 更改为 Point3D,将 new double[]{ ... } 更改为 new Point3D( ... ),将 ( p ) -> p[2] 更改为 ( p ) -> p.z,即可轻松支持

。 =42=]

还有一件事:Java Code Conventions 建议只有当标识符是 classes、接口、枚举等时才以大写字母开头 - 它们不应该用于参数、本地变量或字段。几乎每个人都会假设 Screen.NumberOf.... 是 class Screen 中的静态字段(在将其视为嵌套的 class 后将其视为整数)。 这个想法是,如果我输入 com.Foo.Bar.baz.hmm 大家都知道 com 是一个包名, Foo 是一个 class, Bar 是嵌套的 class Foo$Bar,baz是class中的静态字段Bar,hmm是对象baz.

中的字段