Как делать, чтобы признавать, когда объект изменен в условии while?

Я нашел вещь, которая застала меня с объектами классов в Java.

Я противопоставляю в список статей ListeClauses один goal что изменен каждый раз, когда возможно унифицировать с unif (метод, созданный мной собственный) статья с goal. Поэтому, я хочу начаться снова если только goal уже он не был изменен.

Хотя goal не будь изменен кодом определенно, каждый раз, когда я меняюсь goal, я меняюсь newGoal.

Я думаю, что он из-за newGoal=goal;

    int ir = Clause.ListeClauses.size()-1;
    Clause goal=new Clause();
    goal =(Clause) Clause.ListeClauses.get(ir);
    Clause newGoal =new Clause();
    boolean result = false;

    while (goal!=newGoal){
        newGoal=goal;
        for(int i=0;i<ir;i++){

            Clause c1 =new Clause();
            c1 =(Clause)Clause.ListeClauses.get(i);



            System.out.println("c" +i + ": "+ c1);
            System.out.println("goal: " + goal);

            if (goal.unif(c1)){

                goal.remove(0);
                c1.remove(0);
                goal.addAll(c1);
                System.out.println("UNIFICATION DONE\ngoal: " + goal+"\n**********");

            }
        }
    }

Тогда, этот цикл сделан только однажды из каждого способа, что не то, что я ищу.

Как делать, тогда чтобы признавать, когда был изменен объект?

1
задан 26.03.2016, 08:57
2 ответа

Ты должен быть осторожен со сравнением объектов посредством логических операторов. Если ты сравниваешь, на что два объекта указывают или нет в тот же адрес памяти, он правилен использовать =. Иначе, если ты хочешь сравнить равенство обоих объектов, правильное состоит в том, чтобы использовать equal.

Если ты хочешь проверить, был ли изменен объект заблаговременно, ты можешь сохранять копию объекта перед повторением и в каждом повторении сравнивать настоящий объект с ненастьем посредством equal.

Сейчас, ты говоришь о том, чтобы унифицировать. А именно, если ты хочешь унифицировать объекты, лучший выбор состоит в том, чтобы клонировать их:

newGoal = (Clause) goal.clone();

Эта точка подлежащая обсуждению, так как, как рекомендует Джошуа Блох в Вашей книге Effective Java, он намного лучше делать deep клонировало (глубокое клонирование), а именно, на уровне байт.

3
ответ дан 24.11.2019, 14:41
  • 1
    #161; Осторожно! М и # 233; совсем clone быть должным и # 237; чтобы быть на сочинении и лучше не использовать . –  25.03.2016, 21:33
  • 2
    @LuiggiMendoza и #191; Есть? и #191; И поскольку я могу делать строительный copy с? – IggyPass 25.03.2016, 21:37
  • 3
    @Marine1 ты издаешь твой класс, чтобы его добавляет новый строитель, где я принял объект того же класса. Внутри этого строителя, ты применяешь ее l и # 243; gica необходимая для клонировать объект. Что-то схвати и # 237;: public MiClase(MiClase otro) { this.campo1 = otro.campo1; this.campo2 = otro.campo2; /* lo mismo con todos los campos necesarios */ } –  25.03.2016, 21:47
  • 4
    @Marine1 Посмотри esteejemplo: alvinalexander.com/java/java-deep-clone-example-source-code на c и # 243; mo делать clonaci и # 243; n эффективная, поскольку рекомендует Джошуа Блох. – gugadev 25.03.2016, 22:33
  • 5
    @MitsuGarc и # 237; чтобы быть осторожен с этим. Я участвую в рыцарском турнире aqu и # 237; в сайте есть вопрос, где реализовав эту стратегию в клонировавшем, я он появился и # 243; OutOfMemoryError. –  26.03.2016, 01:51

Ввиду того, что у тебя есть коллекция элементов, и что ты нуждаешься, он состоит в том, чтобы применять некий метод, чтобы объединять все элементы этой коллекции, и если ты используешь Java 8, ты можешь уберегаться весь этот код, использовав streams и метод reduce:

Clause union = new Clause();
Clause.ListeClauses.stream().reduce(union, (clause1, clause2) -> {
    if (clause1.unif(clause2)) {
        clause1.addAll(clause2);
    }
});
System.out.println(union);

В случае, что ты не использовал Java 8, концепция - та же самая: ты должен объединять все результат твоей коллекции применяя какой-то уже определенный метод. Чтобы тебе удается это, ты можешь применять логику, которую он использует Stream#reduce за сценами (pseudo код):

Clause result = null;
for (Clause element : Clause.ListeClauses) {
    if (result == null) {
        //el primero de la lista
        result = element;
    } else {
        //del segundo en adelante
        if (result.unif(element) {
            result.addAll(element);
        }
    }
}
System.out.println(result);
2
ответ дан 24.11.2019, 14:41