2016-01-30 48 views
1

我做一个Java项目,并已经建造了一个多边形是这样的: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); 

,而类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元素的正确语法? (或者我怎么能得到那个数额?)

+0

你有没有考虑过使用for循环? – bhspencer

+1

你在构造函数中增加'NumberOf3DPolygons';大概你宣布'DPolygons []'为'new DPolygons [SOME_NUMBER]',否则你会得到一个IndexOutOfBoundsException。没有'DPolygons [NumberOf3DPolygons]',只有'DPolygons [NumberOf3DPolygons -1]'。 – Kenney

+0

Screen.NumberOf3DPolygons ++是做什么的?它是否与您用于DPolygons [NumberOf3DPolygons]的索引相同? – SomeDude

回答

0

我想要做的是计算其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; 
    } 
} 

一个例子,如果有三维多边形的数组:

//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值的多边形等。

有发生在你的情况2点的可能性为NullPointerException

  1. 你没有初始化的z在DPolygon类的数组。
  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}; 
    } 
} 
+0

您只需要将getSumOfZ()的返回类型从void更改为double;) – Toni92

+0

@ Toni92 Yup,粗心的错误。 – user3437460

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

    } 
+0

这是不正确的。正确阅读问题。 OP询问关于将特定D多边形的z坐标求和而不是所有z的求和。另外z是双向量。 – SomeDude

0

是全局变量z申明public吗?

public double z; 

不过,我会建议创建Dpolygon类中的公共方法来检索全球Z值和使用而不是吸除直接调用的属性。

里面的类:

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

设计类这样...

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

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

0

有两个整齐的概念来介绍的题目是Collections和,在Java 1.8新的StreamsReduction

使用List将消除尝试使用全局变量管理动态数组所导致的NullPointerException。 在你的情况下,在DPolygon的构造函数中增加Screen.NumberOf3DPolygons并不适合它。如果构建另一个DPolygon而不将其添加到该阵列,会发生什么情况?您希望使该变量与添加到列表中的元素数量一致,在管理阵列的对象中使用add方法。幸运的是,这已经在Java 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) -> p.z

还有一件事:Java Code Conventions建议只有当它们是类,接口,枚举等时,标识符才以大写字母开头 - 它们不应用于参数,局部变量或字段。几乎所有人都会认为Screen.NumberOf....是类Screen中的一个静态字段(通过将它看作一个整数来解除它作为一个嵌套类之后)。 的想法是,如果我键入com.Foo.Bar.baz.hmm大家都知道,com是包名,Foo是一类,Bar是嵌套类Foo$BarbazBar类的静态字段,hmm是对象baz的领域。

+0

谢谢你的详细解答。这肯定会是更优雅的解决方案。我尝试了upvote的帖子,但我没有足够的声望呢。 – Toni92