2016-01-30 98 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