java - 这个设计有什么问题导致无限循环?

标签 java recursion stack-overflow infinite-loop

我将通过给您一个描述性示例来解释自己。假设我正在编写一个非常简单的云存储模拟,一个简单的终端程序。我有两个主要类,用户和文件,编码如下:

class User {
       Set<File> sharedFiles;
       void shareFile(File f){
           sharedFiles.add(f);
           f.shareWith(this);
       }
}

class File {
       Set<User> sharedUsers;
       void shareWith(User u){
           sharedUsers.add(u);
           u.shareFile(this);
       }
}

我假装有权访问已共享给用户的文件以及已共享文件的用户,因此我对列表进行了编码 sharedFilessharedUsers .

那么,我会:

main(){
    User u = new User();
    File f = new File();
    u.shareFile(f); // or f.shareWith(u), doesn't matter
}

我知道这是一个非常明显的无限循环情况。事实上,这段代码会导致 Exception in thread "main" java.lang.StackOverflowError 。两种方法都会无限期地互相调用。

那么,在您看来,这个问题的理想解决方案以及这两个类的良好设计是什么?

最佳答案

您可以在调用 shareWith 方法之前添加检查一个类的对象是否已持有对另一类的对象的引用:

class User {
       Set<File> sharedFiles;
       boolean hasFile (File f) {
           return sharedFiles.contains(f);
       }
       void shareFile(File f){
           sharedFiles.add(f);
           if (!f.hasUser(this))
               f.shareWith(this);
       }
}

class File {
       Set<User> sharedUsers;
       boolean hasUser (User u) {
           return sharedUsers.contains(u);
       }
       void shareWith(User u){
           sharedUsers.add(u);
           if (!u.hasFile(this))
               u.shareFile(this);
       }
}

编辑:当然,此代码缺少 sharedUserssharedFiles 集的初始化,但我假设您在实际代码中具有该初始化。

关于java - 这个设计有什么问题导致无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46218512/

相关文章:

c++ - 红黑树插入 - 递归问题 - C++

c - 多线程快速排序堆栈溢出

java - 如何使用 "findBy"方法?

java - 尽管推断出 Long,但 Collectors.maxBy(Comparator.naturalOrder()) 无法编译

java - 为什么 Apache POI XSSF 无法写入 servlet 响应输出流?

c# - 当我只能生成其他可观察对象时,如何从起始可观察对象生成可观察对象?

Android:EditText TextChangedListener 上的堆栈溢出错误

java - 对象之间是否可以通过相互引用使彼此“不可删除”?

c# - 生成不同位数的随机数

c - 递归释放C中的TRIE结构