繁体   English   中英

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

[英]Java: Accessing elements of a row in a multidimensional array?

我正在做一个Java项目,并构造了一个Polygon,如下所示:

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

而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类中创建一个公共方法来检索全局z值,并使用该getter而不是直接调用该属性。

课堂内:

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

这样设计课程...

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

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

我想做的是计算其z坐标的总和(在这种情况下为= 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

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

在您的情况下, NullPointerException可能有两种发生:

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

确保从DPolygon类初始化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和Java 1.8的新增功能Reduction of Streams

使用列表可以消除NullPointerExceptions,这是由于尝试使用全局变量管理动态数组而导致的。 在您的情况下,在Screen.NumberOf3DPolygons的构造函数中递增Screen.NumberOf3DPolygons DPolygon 如果构造另一个DPolygon而不将其添加到该数组会发生什么? 您可能想要使用管理数组的对象中的add方法,使该变量与添加到列表中的元素的数量一致。 幸运的是,这已经在Java Collections类中为我们完成了。

这是使用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类:

    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 ) -> pz ,可以轻松地支持它。

还有一件事: Java代码约定建议仅当标识符是类,接口,枚举等时,标识符才使用大写字母开头-不应将其用于参数,局部变量或字段。 几乎每个人都会假设Screen.NumberOf....Screen类中的静态字段(通过将其用作整数来消除它是一个嵌套类后)。 这个想法是,如果我输入com.Foo.Bar.baz.hmm每个人都知道com是一个包名称, Foo是一个类, Bar是嵌套的类Foo$BarbazBar和class hmm的静态字段是对象baz的字段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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