私はオブジェクトのプライベートリストを含むクラスを持っています。javaオブジェクトを独自のgetComponentTypeにキャストする方法は?
(1)のaddObject
public void addObject(Object obj)
{
this.mylist.add(obj);
}
(2) dropObject
dropObjectは少しトリッキーである:
private List<Object> mylist;
さらに私のクラスには、二つの方法を含んでいます。私は最初の要素をobj
と等しい(しかし同じではない)mylist
から削除したいと思います。したがって、パラメータobj
のクラスをすべての要素のクラスmylist
に比較します。現在の要素のクラスが一致する場合は、両方の要素が等しいかどうか(同じではない)を比較したいと思います。
ここでは、配列を互いに比較するのに問題があります。私はobj
とcurr_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
いくつかの追加に関する情報は:
- 私は私のメソッドは、クラスまたはデータ型のオブジェクトから独立を取得できるようにするためのパラメータとして
Object obj
を使用したいです。 - 私は、それぞれのデータ型自体を扱うために私のメソッドを単純にオーバーロードすることができることを知っています。しかし、私はこの一般的な問題を解決しようとします。
更新
私はダルシャンメータの提案に従い、ラッパークラスにプリミティブから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);
}
}
'(obj.equals(curr_obj)場合の何が問題になってい{objRemove = curr_obj;}?' – ADS
配列は、それと比較することができない 'INT [] iArr1 = {0,1,2}'。 –