#java
Вопрос:
Я хочу сравнить объект A с объектом B класса Fruit.
Я хочу получить значение true, если значение файла объекта равно значению файла объекта B
Я знаю, что A == B сравнивает адрес. Поэтому мне нужно переопределить равенства для сравнения.
Но в моем классе есть много областей.
Я создаю код для сравнения
@Setter
@Getter
public class Fruit {
//if I have 100 Filed
int filed1;
int filed2;
int filed3;
int filed4;
....
@Override
public boolean equals(Object obj) {
if(obj instanceof Fruit) {
Fruit target = (Fruit)obj;
// I want to compare this object with targetFooResponse
if(this.getFiled1() != target.getFiled1()) {
return false;
}
if(this.getFiled2() != target.getFiled2()) {
return false;
}
//I need to add if condition of 98 in the future
return true;
}else {
return false;
}
}
}
Я думаю, что мой код очень неэффективен.Я хочу уменьшить, если условия
Есть ли хороший способ сравнить?
Комментарии:
1. Ваш код уродлив, потому что иметь класс со 100 полями — ужасная идея. Но если это то, что у вас есть, то это не худший способ сравнить их. Кроме того, это «поле», а не «подано».
2. единственная оптимизация, которую я мог бы сделать, — это связать условия с
amp;amp;
оператором:this.getFiled1() == target.getFiled1 amp;amp; this.getFiled2 == target.getFIled2() ...
3. Полностью согласен с Йоахимом Зауэром, вот почему у нас есть концепция массива … Если вы еще не подвергли себя воздействию массива, найдите его…
4.
Arrays.stream(getClass().getFields()).map(f->{if(!f.getName().startsWith("filed")) return true;f.setAccessible(true);try {return f.get(this).equals(f.get(obj));} catch (IllegalAccessException e) {e.printStackTrace();}return false;}).allMatch(e -> e)
вернет, равны ли всеfiledN
поля для двух объектов, но это грязный способ сделать это
Ответ №1:
Как уже упоминали другие, иметь класс со 100 полями-плохая идея. Это нарушает многие хорошие инженерные принципы SW.
Тем не менее, допустим, у вас есть класс со многими полями ( может быть, он генерируется автоматически? )
Вот милая идея. Если вы можете сделать свой класс сериализуемым , и все поля для проверки сериализуемы, вы можете сбросить каждый объект в поток массива байтов и сравнить потоки.
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
class A implements Serializable {
int a;
int b;
int c;
}
public class Example {
public static void main(String[] args) throws IOException {
A a1 = new A(); a1.a = 1; a1.b = 2; a1.c = 3;
A a2 = new A(); a2.a = 1; a2.b = 2; a2.c = 3;
byte[] bytes1 = getBytes(a1);
byte[] bytes2 = getBytes(a2);
System.out.println(Arrays.equals(bytes1,bytes2));
}
private static byte[] getBytes(A a) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);) {
out.writeObject(a);
out.flush();
return bos.toByteArray();
}
}
}
Комментарии:
1. Мне было бы неудобно ссылаться на сериализацию в
equals()
реализации. Я не пробовал, но не удивлюсь, если сериализация и объектequals()
в какой-то момент включат вызов, который может привести к бесконечной рекурсии.2. @JoachimSauer Ну , в моем примере этого нет ( переопределение для класса A), но кто знает, может быть, в некоторых сценариях.
3. Это милая идея. Спасибо