В C ++ у нас есть ссылки. Но в Java, как лучше всего «перевести» один и тот же код с копированием по значению? - PullRequest
3 голосов
/ 17 марта 2012

Может быть, я просто запутался ни в чем, но здесь идет речь:

Во многих случаях у нас есть рекурсивный алгоритм, в котором значения, которые нам нужны, изменяются при переходе от одной рекурсии к другой.
Примеры могут быть min max maxNoOfNodes и т. Д.

В C ++ можно передавать различные параметры в качестве ссылок, и все работает нормально.

В Java это не может работать, поскольку все копируется по значению, и поэтому необходимо создать дополнительный класс для аргумента в качестве держателя, чтобы изменить его внутри функции.
Так что в C ++:

int findLargestSeq(Tree *p, int &min, int &max,Tree *& seqTree)

не может быть "переведен", как в Java, но должен выглядеть так:
int findLargestSeq(Tree p, Params p)
, где Params будет инкапсулировать min max и т. Д. Будет обновлено.

Мне было интересно, это единственный путь?
Есть ли более "чистый" подход или стандартный шаблон в Java для такого рода алгоритмов?

Я думаю, что, возможно, тот факт, что мы модифицируем аргументы, которые передаются как ссылки в C ++, является привычкой, оставшейся от программирования на C, тогда как в Java, которая является чисто ОО, я также застрял, думая об этомпроцедурным образом и не вижу, что я должен как-то решать подобные проблемы по-другому.

Любой ввод приветствуется

Ответы [ 5 ]

2 голосов
/ 17 марта 2012

Когда алгоритм достаточно сложен, чтобы требовать рекурсивных вызовов, чтобы иметь возможность изменять переменные состояния по мере их продолжения, тогда очень простым решением является использование частных полей в вашем классе.

2 голосов
/ 17 марта 2012

В Java все копируется.Однако, кроме примитивов (int, boolean, char и т. Д.), Все остальное является указателем.

В Java, если вы хотите вернуть несколько значений, вы создаете класс-агрегатор, который содержит несколько значений,Если вы действительно хотите иметь метод void или метод, в котором указанные параметры модифицируются методом для возврата результатов, вы можете использовать шаблон Holder .

1 голос
/ 17 марта 2012

Java предпочитает использовать объекты и поддерживает только ссылки на объекты, а не примитивы.

Один из способов реинтеграции

int findLargestSeq(Tree *p, int &min, int &max,Tree *& seqTree)

есть

int findLargestSeq(Tree p, int[] min, int[] max,Tree[] seqTree)

который можно назвать

Tree p = ...
int[] min = { 0 };
int[] max = { Integer.MAX_VALUE };
Tree[] seqTree = { tree };

int ret = findLargestSeq(p, min, max, seqTree);
1 голос
/ 17 марта 2012

Можно ли передать параметры по ссылке в Java?

Использовать шаблон AtomicReference.Это выглядит ужасно и долго, но я думаю, что это даст вам поведение, которое вы ищете.

0 голосов
/ 17 марта 2012

В Java вы передаете не копию значения, а копию ссылки.

Вы не можете изменить ссылку, позволив ей указать на другой объект внутри метода, но - если у объекта есть методы для его изменения - измените объект, на который есть ссылка.

void failToModify (Foo foo) {
    foo = new Bar (); // Useless
}

void modify (Foo foo) {
    foo.setFoo (new Bar ()); 
}

Обратите внимание, что это согласуется с массивами:

void failToModify (int[] ia) {
    ia = {3, 4, 5}; // No influence for the caller
}

void modify (int[] ia) {
    ia[0] = 3;
    ia[1] = 4;
    ia[2] = 5;
}

И со встроенными типами тоже:

void failToModify (int a) {
    a = 8; // No influence for the caller
}

void modifyImpossible (int a) {
    --a; 
    // a build in type is immutable. 
    // You can't modify 8 to be 7.
    // Only the local copy of the reference is decremented.
}

modifyImpossible (8);
int a = 7;
failToModify (a);

У вас есть 2 возможности: либо изменить параметр, если он не 't неизменным или вернуть свежий, новый объект.В рекурсивном методе вы можете передавать sofar-Object от шага к шагу (например, minSofar).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...