Java 有没有更有效的方法在递归中传递对象参数?
我想用Java做递归,传递对象参数。大概是这样的:Java 有没有更有效的方法在递归中传递对象参数?,java,recursion,Java,Recursion,我想用Java做递归,传递对象参数。大概是这样的: int recursion(Object object) { //do a little bit modification to the object int i1= recursion(modified_object_1); //do a little bit modification to the object int i2= recursion(modified_object_2); //do a
int recursion(Object object)
{
//do a little bit modification to the object
int i1= recursion(modified_object_1);
//do a little bit modification to the object
int i2= recursion(modified_object_2);
//do a little bit modification to the object
int i3= recursion(modified_object_3);
return max(i1, i2, i3);
}
现在,因为对象是通过引用传递的,所以我必须克隆对象参数3次,然后将克隆的对象传递给下一个递归。然而,这可能是非常低效的,因为我做了数万次递归,而且对象的结构非常复杂。除了克隆对象之外,还有更有效的方法吗
谢谢~我认为你无法避免复制那些对象 我建议构建一个pre函数,从这些对象中提取所需的一切,以便构建某种“尽可能小的对象”,以便在递归中复制尽可能少的字段
最好的方法是提取基本类型并将其用于递归。无论如何,要获得更具体的帮助,您应该发布更多详细信息(例如,您的对象/修改)我认为您无法避免复制这些对象 我建议构建一个pre函数,从这些对象中提取所需的一切,以便构建某种“尽可能小的对象”,以便在递归中复制尽可能少的字段
最好的方法是提取基本类型并将其用于递归。无论如何,要获得更具体的帮助,您应该发布更多详细信息(例如,您的对象/修改)在java中,您不能通过引用传递参数,而只能通过值传递参数。在您的例子中,一个可能的解决方法是将对象定义为
递归
方法所在的类的属性。例如:
class RecursionClass {
private Object object;
public void setObject(Object object) {
this.object = object;
}
int recursion() {
if(object == null)
throw new Exception("Set the object first!");
// define modified objects base on object
//do a little bit modification to the object
int i1= recursion(modified_object_1);
//do a little bit modification to the object
int i2= recursion(modified_object_2);
//do a little bit modification to the object
int i3= recursion(modified_object_3);
return max(i1, i2, i3);
}
}
在java中,不能通过引用传递参数,只能通过值传递参数。在您的例子中,一个可能的解决方法是将对象定义为
递归
方法所在的类的属性。例如:
class RecursionClass {
private Object object;
public void setObject(Object object) {
this.object = object;
}
int recursion() {
if(object == null)
throw new Exception("Set the object first!");
// define modified objects base on object
//do a little bit modification to the object
int i1= recursion(modified_object_1);
//do a little bit modification to the object
int i2= recursion(modified_object_2);
//do a little bit modification to the object
int i3= recursion(modified_object_3);
return max(i1, i2, i3);
}
}
首先是关于传递值和引用的一些明确性(OP在这方面似乎很清楚,但评论者似乎很困惑)。Java对象在传递给函数时不会自动克隆-对对象的引用是通过值传递的-更改函数中的对象将改变调用上下文中的对象 因此OP正确地计划,要运行他的算法,他需要首先克隆对象,然后使用克隆的副本传递递归函数链 然而,在某些情况下,还有一种可能很容易实现:
int recursion(Object object)
{
//do a little bit modification to the object
int i1= recursion(object);
//undo the modification to the object
//do a little bit modification to the object
int i2= recursion(object);
//undo the modification to the object
//do a little bit modification to the object
int i3= recursion(object);
//undo the modification to the object
return max(i1, i2, i3);
}
在可能的情况下(例如在搜索游戏决策树时选择可能的移动),它的工作效率更高
请注意,最后一次撤消更改是必需的,否则堆栈上较高的对象将出错。首先,关于通过值和引用进行传递有点清楚(OP对此似乎很清楚,但评论者似乎很困惑)。Java对象在传递给函数时不会自动克隆-对对象的引用是通过值传递的-更改函数中的对象将改变调用上下文中的对象 因此OP正确地计划,要运行他的算法,他需要首先克隆对象,然后使用克隆的副本传递递归函数链 然而,在某些情况下,还有一种可能很容易实现:
int recursion(Object object)
{
//do a little bit modification to the object
int i1= recursion(object);
//undo the modification to the object
//do a little bit modification to the object
int i2= recursion(object);
//undo the modification to the object
//do a little bit modification to the object
int i3= recursion(object);
//undo the modification to the object
return max(i1, i2, i3);
}
在可能的情况下(例如在搜索游戏决策树时选择可能的移动),它的工作效率更高
请注意,最后一次撤消更改是必需的,否则堆栈上层的对象将出错。请考虑使用不可变对象。当堆栈帧共享正在修改的对象时,递归算法变得特别难以考虑 Decorator模式有助于提高效率和内存使用率。例如,如果要更改一个字段:
class UserWithAgeChanged implements User {
private User delegate;
private int age;
public UserWithAgeChanged(User user, int newAge) {
this.delegate = user;
this.age = newAge;
}
@Override
public String getName() {
return delegate.getName();
}
// similar methods for all delegated fields
@Override
public String getAge() {
return age;
}
}
(有一些图书馆可以帮助你做这类事情,比如
现在,您可以执行以下递归操作:
// silly functionality, but you get the point
void recurse(User user) {
if(user.getAge() == 44) {
return user;
} else {
recurse(new UserWithAgeChanged(user, user.getAge() + 1);
}
}
这将创建一个代理链,大多数是小对象,最后是更大的“根”
User
对象。在一个更复杂的算法中,您将得到一个由不可变对象组成的网络,但不会有太多的复制或克隆进行,而是会有大量的委托。考虑使用不可变对象。当堆栈帧共享正在修改的对象时,递归算法变得特别难以考虑
Decorator模式有助于提高效率和内存使用率。例如,如果要更改一个字段:
class UserWithAgeChanged implements User {
private User delegate;
private int age;
public UserWithAgeChanged(User user, int newAge) {
this.delegate = user;
this.age = newAge;
}
@Override
public String getName() {
return delegate.getName();
}
// similar methods for all delegated fields
@Override
public String getAge() {
return age;
}
}
(有一些图书馆可以帮助你做这类事情,比如
现在,您可以执行以下递归操作:
// silly functionality, but you get the point
void recurse(User user) {
if(user.getAge() == 44) {
return user;
} else {
recurse(new UserWithAgeChanged(user, user.getAge() + 1);
}
}
这将创建一个代理链,大多数是小对象,最后是更大的“根”
User
对象。在更复杂的算法中,您将得到一个由不可变对象组成的网络,但不会有太多的复制或克隆操作,而是会有大量的委托。如果需要数万次递归,请在对象定义中设置一个递归周期。或者详细说明你想要达到的目标以及对对象的那些微小的修改,你可能会考虑删除递归方法来实现动态编程迭代方法,类似于经典的斐波那契程序,人们总是在介绍类中使用一个修正,你是通过值传递对象,通过引用传递对象(即在内存中传递对象的地址)是最有效的方法。尽管如此,在JavaJava中不可能总是按值传递参数……这似乎是一个XY问题(为什么必须使用递归?),但为了给出一个直接的答案,我想说,为什么不在递归调用后立即传递原始对象并撤销更改?如果需要数万个参数,请在对象定义中设置一个递归周期