toString() 中的无限递归,如何防止这种情况发生?
Infinite recursion in toString(), how can I prevent this?
我通过 Whosebug 进行了搜索,试图解决这个问题 "on my own",但没有成功。我想我正面临 toString()
方法中的无限递归问题,但我不确定,因为我对此很陌生。
我认为首先向您提供我的代码会使问题对您来说更清楚:
import java.util.ArrayList;
public class User{
private String name;
private ArrayList<User> friends;
private static ArrayList<User> users = new ArrayList<User>();
public User(String name){
this.name = name;
this.friends = new ArrayList<User>();
users.add(this);
}
public void addFriend(User friend){
friends.add(friend);
}
public static void connect(User user1, User user2){
user1.addFriend(user2);
user2.addFriend(user1);
}
public static ArrayList<User> getUsers(){
return users;
}
public String toString(){
return String.format("%s : %s", name, friends);
}
}
我不确定你是否能看到我正在尝试做的事情,但我的 toString
的格式应该是这样的:
姓名:{friend1, friend2, friend3, ...}
例如,用户“Alice”和朋友“Bob”和“Charlie”会这样打印
爱丽丝:{鲍勃,查理,}
我不太确定我应该如何着手实现这一目标。任何帮助将非常感激。如果之前已经回答过这个问题,我也很抱歉,但我不明白我之前找到的任何答案。
这是我的main
-方法,可能也有帮助:
public class Main{
public static void main(String args[]){
User bob = new User("Bob");
User alice = new User("Alice");
User charlie = new User("Charlie");
User.connect(alice, bob);
User.connect(alice, charlie);
System.out.println(User.getUsers());
}
}
您需要遍历 "friends" 列表并打印每个列表的名称。因为你要打印每个朋友,这包括朋友的朋友,这就是你得到无限递归的原因。
试试
public String toString() {
int count = 0;
StringBuilder sb = new StringBuilder("{\"name\"=" + name + ", \"friends\"=[");
for (User friend : friends) {
sb.append(friend.getName());
if (++count < friends.size()) sb.append(", ");
}
sb.append("]}");
return sb.toString();
}
我怀疑问题在于,当您调用 Alice.toString()
并开始遍历 Alice 的朋友列表时,它会调用每个朋友的 toString()
。
如果 Alice
是 Bob
的朋友,并且 Bob
也是 Alice
的朋友,那么您最终会在 Alice.toString()
之间来回跳动Bob.toString()
无限期。
从我的角度来看,问题可能是一旦你调用 toString,试图显示所有用户,发生的事情是在 toString 方法中你调用了朋友的 toString os 用户,先后。
为了避免递归,尝试遍历用户的好友列表,将用户的好友信息拼接成一个空字符串,不再声明好友的好友。总结一下,避免递归:)
我通过 Whosebug 进行了搜索,试图解决这个问题 "on my own",但没有成功。我想我正面临 toString()
方法中的无限递归问题,但我不确定,因为我对此很陌生。
我认为首先向您提供我的代码会使问题对您来说更清楚:
import java.util.ArrayList;
public class User{
private String name;
private ArrayList<User> friends;
private static ArrayList<User> users = new ArrayList<User>();
public User(String name){
this.name = name;
this.friends = new ArrayList<User>();
users.add(this);
}
public void addFriend(User friend){
friends.add(friend);
}
public static void connect(User user1, User user2){
user1.addFriend(user2);
user2.addFriend(user1);
}
public static ArrayList<User> getUsers(){
return users;
}
public String toString(){
return String.format("%s : %s", name, friends);
}
}
我不确定你是否能看到我正在尝试做的事情,但我的 toString
的格式应该是这样的:
姓名:{friend1, friend2, friend3, ...}
例如,用户“Alice”和朋友“Bob”和“Charlie”会这样打印
爱丽丝:{鲍勃,查理,}
我不太确定我应该如何着手实现这一目标。任何帮助将非常感激。如果之前已经回答过这个问题,我也很抱歉,但我不明白我之前找到的任何答案。
这是我的main
-方法,可能也有帮助:
public class Main{
public static void main(String args[]){
User bob = new User("Bob");
User alice = new User("Alice");
User charlie = new User("Charlie");
User.connect(alice, bob);
User.connect(alice, charlie);
System.out.println(User.getUsers());
}
}
您需要遍历 "friends" 列表并打印每个列表的名称。因为你要打印每个朋友,这包括朋友的朋友,这就是你得到无限递归的原因。
试试
public String toString() {
int count = 0;
StringBuilder sb = new StringBuilder("{\"name\"=" + name + ", \"friends\"=[");
for (User friend : friends) {
sb.append(friend.getName());
if (++count < friends.size()) sb.append(", ");
}
sb.append("]}");
return sb.toString();
}
我怀疑问题在于,当您调用 Alice.toString()
并开始遍历 Alice 的朋友列表时,它会调用每个朋友的 toString()
。
如果 Alice
是 Bob
的朋友,并且 Bob
也是 Alice
的朋友,那么您最终会在 Alice.toString()
之间来回跳动Bob.toString()
无限期。
从我的角度来看,问题可能是一旦你调用 toString,试图显示所有用户,发生的事情是在 toString 方法中你调用了朋友的 toString os 用户,先后。
为了避免递归,尝试遍历用户的好友列表,将用户的好友信息拼接成一个空字符串,不再声明好友的好友。总结一下,避免递归:)