2017-08-16 13 views
1

私はオブジェクトのプライベートリストを含むクラスを持っています。javaオブジェクトを独自のgetComponentTypeにキャストする方法は?

(1)のaddObject

public void addObject(Object obj) 
{ 
    this.mylist.add(obj); 
} 

(2) dropObject

dropObjectは少しトリッキーである:

private List<Object> mylist; 

さらに私のクラスには、二つの方法を含んでいます。私は最初の要素をobjと等しい(しかし同じではない)mylistから削除したいと思います。したがって、パラメータobjのクラスをすべての要素のクラスmylistに比較します。現在の要素のクラスが一致する場合は、両方の要素が等しいかどうか(同じではない)を比較したいと思います。

ここでは、配列を互いに比較するのに問題があります。私はobjcurr_objの両方の型変換を必要とするArray.deepEquals()を使用したいと思います。

だからここに私のコードです:

public void dropArgument(Object obj) { 

    if (obj == null) { 
     return; 
    } 

    Object objRemove = null; 

    for (Object curr_obj : this.mylist) { 

     if (curr_obj.getClass() != obj.getClass()) { 
      continue; 
     } 

     // primitive data type comparison 
     if (obj.getClass().isPrimitive() && curr_obj == obj) { 
      objRemove = curr_obj; 
     } 
     // array comparison 
     else if ((obj.getClass().isArray()) 
       /* the following line gives me headache */ 
       && (Arrays.deepEquals((Object[]) curr_obj, (Object[]) obj))) { 
      objRemove = curr_obj; 
     } 
     // wrapper/collection comparison 
     else if (curr_obj.equals(obj)) { 
      objRemove = curr_obj; 
     } 
     // comparison of any other classes which are assumed not to have an 'equals' method. 
     else { 
      Field[] fInputFields = obj.getClass().getDeclaredFields(); 
      Field[] fFields = curr_obj.getClass().getDeclaredFields(); 
      if (Arrays.deepEquals(fInputFields, fFields)) { 
       objRemove = curr_obj; 
      } 
     } 
    } 

    // delete obj match if found 
    if (objRemove != null) { 
     this.mylist.remove(objRemove); 
    } 
} 

私は、このメソッドのテストを書いて、配列のすべての種類は、以下の(int型[]配列のstackstrace)のget:

error: 
java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Object; 
    at javafxTablePane.FieldMethodData.dropArgument(FieldMethodData.java:119) 
    at tests.DropArgumentsTests.test_dropMultiArrayInteger(DropArgumentsTests.java:345) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 

誤りがありますクリア:int[]Object[]に型キャストできません。だから私の質問は、Array.deepEquals()は型キャストが必要なので、どのように自分のオブジェクトを自分のクラス/データ型に配列として再キャストできますか?

私はこれを検索し、getClass().getComponentType()メソッドが見つかりました、私のオブジェクトの配列型を提供します。しかし、私はそれを独自の配列型に型キャストするためにどのように使用するのかはわかりません(可能であれば)。obj

いくつかの追加に関する情報は:

  1. 私は私のメソッドは、クラスまたはデータ型のオブジェクトから独立を取得できるようにするためのパラメータとしてObject objを使用したいです。
  2. 私は、それぞれのデータ型自体を扱うために私のメソッドを単純にオーバーロードすることができることを知っています。しかし、私はこの一般的な問題を解決しようとします。

更新

私はダルシャンメータの提案に従い、ラッパークラスにプリミティブから1次元配列に変換する簡単な方法を実装しました。それで、より一般的なコード(例:任意の次元のキャスト配列)を開発し続けることができるので、この解決策は私の問題に適しています。興味のある人のために私のコードをここに入れました。

/** 
* <b>ArrayEquals</b> 
* <p> 
* Compares two arrays of any same class and delivers their equality as boolean. 
* </p> 
* 
* @param obj1 
*   [Object] : any object of any class as Object 
* @param obj2 
*   [Object] : any object of the same class as obj1 as Object 
* @return [boolean] : Equality of obj1 and obj2 
*/ 
private boolean ArrayEquals(Object obj1, Object obj2) { 

    Class<?> cObj1 = obj1.getClass().getComponentType(); 

    // convert byte[] to Byte[] 
    if (cObj1.equals(byte.class)) { 

     byte[] tmpObj1 = (byte[]) obj1; 
     byte[] tmpObj2 = (byte[]) obj2; 
     if (tmpObj1.length != tmpObj2.length) { 
      return false; 
     } 
     Byte[] newObj1 = new Byte[tmpObj1.length]; 
     Byte[] newObj2 = new Byte[tmpObj2.length]; 

     for (int i = 0; i < tmpObj1.length; i++) { 
      newObj1[i] = tmpObj1[i]; // Autoboxing 
      newObj2[i] = tmpObj2[i]; // Autoboxing 
     } 
     return Arrays.deepEquals(newObj1, newObj2); 
    } 
    // convert short[] to Short[] 
    else if (cObj1.equals(short.class)) { 
     short[] tmpObj1 = (short[]) obj1; 
     short[] tmpObj2 = (short[]) obj2; 
     if (tmpObj1.length != tmpObj2.length) { 
      return false; 
     } 
     Short[] newObj1 = new Short[tmpObj1.length]; 
     Short[] newObj2 = new Short[tmpObj2.length]; 

     for (int i = 0; i < tmpObj1.length; i++) { 
      newObj1[i] = tmpObj1[i]; // Autoboxing 
      newObj2[i] = tmpObj2[i]; // Autoboxing 
     } 

     return Arrays.deepEquals(newObj1, newObj2); 
    } 
    // convert int[] to Integer[] 
    else if (cObj1.equals(int.class)) { 
     Integer[] newObj1 = Arrays.stream((int[]) obj1).boxed().toArray(Integer[]::new); 
     Integer[] newObj2 = Arrays.stream((int[]) obj2).boxed().toArray(Integer[]::new); 
     return Arrays.deepEquals(newObj1, newObj2); 
    } 
    // convert long[] to Long[] 
    else if (cObj1.equals(long.class)) { 
     Long[] newObj1 = Arrays.stream((long[]) obj1).boxed().toArray(Long[]::new); 
     Long[] newObj2 = Arrays.stream((long[]) obj2).boxed().toArray(Long[]::new); 
     return Arrays.deepEquals(newObj1, newObj2); 
    } 
    // convert float[] to Float[] 
    else if (cObj1.equals(float.class)) { 
     float[] tmpObj1 = (float[]) obj1; 
     float[] tmpObj2 = (float[]) obj2; 
     if (tmpObj1.length != tmpObj2.length) { 
      return false; 
     } 
     Float[] newObj1 = new Float[tmpObj1.length]; 
     Float[] newObj2 = new Float[tmpObj2.length]; 

     for (int i = 0; i < tmpObj1.length; i++) { 
      newObj1[i] = tmpObj1[i]; // Autoboxing 
      newObj2[i] = tmpObj2[i]; // Autoboxing 
     } 

     return Arrays.deepEquals(newObj1, newObj2); 
    } 
    // convert double[] to Double[] 
    else if (cObj1.equals(double.class)) { 
     double[] tmpObj1 = (double[]) obj1; 
     double[] tmpObj2 = (double[]) obj2; 
     if (tmpObj1.length != tmpObj2.length) { 
      return false; 
     } 
     Double[] newObj1 = new Double[tmpObj1.length]; 
     Double[] newObj2 = new Double[tmpObj2.length]; 

     for (int i = 0; i < tmpObj1.length; i++) { 
      newObj1[i] = tmpObj1[i]; // Autoboxing 
      newObj2[i] = tmpObj2[i]; // Autoboxing 
     } 

     return Arrays.deepEquals(newObj1, newObj2); 
    } 
    // convert boolean[] to Boolean[] 
    else if (cObj1.equals(boolean.class)) { 
     boolean[] tmpObj1 = (boolean[]) obj1; 
     boolean[] tmpObj2 = (boolean[]) obj2; 
     if (tmpObj1.length != tmpObj2.length) { 
      return false; 
     } 
     Boolean[] newObj1 = new Boolean[tmpObj1.length]; 
     Boolean[] newObj2 = new Boolean[tmpObj2.length]; 

     for (int i = 0; i < tmpObj1.length; i++) { 
      newObj1[i] = tmpObj1[i]; // Autoboxing 
      newObj2[i] = tmpObj2[i]; // Autoboxing 
     } 

     return Arrays.deepEquals(newObj1, newObj2); 
    } 
    // convert char[] to Character[] 
    else if (cObj1.equals(char.class)) { 
     char[] tmpObj1 = (char[]) obj1; 
     char[] tmpObj2 = (char[]) obj2; 
     if (tmpObj1.length != tmpObj2.length) { 
      return false; 
     } 
     Character[] newObj1 = new Character[tmpObj1.length]; 
     Character[] newObj2 = new Character[tmpObj2.length]; 

     for (int i = 0; i < tmpObj1.length; i++) { 
      newObj1[i] = tmpObj1[i]; // Autoboxing 
      newObj2[i] = tmpObj2[i]; // Autoboxing 
     } 
     return Arrays.deepEquals(newObj1, newObj2); 
    } 
    // is no primitive 
    else { 
     return Arrays.deepEquals((Object[]) obj1, (Object[]) obj2); 
    } 
} 
+0

'(obj.equals(curr_obj)場合の何が問題になってい{objRemove = curr_obj;}?' – ADS

+0

配列は、それと比較することができない 'INT [] iArr1 = {0,1,2}'。 –

答えて

3

あなたは2つのオブジェクトを比較しているとして、あなたがすべき次

  • は新しい方法に比較ロジックを抽出する(例えば、private boolean equals(Object o1, Object o2)を呼び出し、dropObjectメソッドから呼び出してください)。
  • Array型では、array.getClass().getComponentType()メソッド呼び出しを使用してコンポーネントタイプを取得し、適切な配列にキャストしようとします。 int配列をObject配列にキャストすると、ClassCastExceptionが送出されます。キャストと配列の種類の詳細については、this SO答えを参照してください。
  • コンポーネント型が配列の場合は、すべての要素を反復処理するロジックを実装し、各要素に対してメソッドを呼び出します。
+0

私はそれを試してみましょう! –

+0

'Integer []'を 'Object []にキャスティングすると、' int [] iArr2 = {0,1,2} ] 'は例外にはなりませんが、' int [] 'を' Object [] 'にキャストすると、 – VGR

+0

@ VGRは答えを更新しました。 –

関連する問題