自动删除已删除对象的对象
Automatically removing object(s) of a removed object
我有三个 类 正在使用。 1)Category
2)MainCategory
3)SubCategory
Category
:负责creating/removing个主要类别
MainCategory
:负责 creating/removing 个子类别(并将它们嵌套在各自的主类别下)
SubCategory
:Sets/gets自己实例的名称
我遇到的问题是,当我删除一个主要类别对象(使用 .remove)时,它下面的子类别仍然存在并转移到下一个主要类别。我真的希望它们一起被删除,以防它们的(父)类别被删除。我在 post 末尾的 Main 方法中的注释中指出了问题。谢谢。
## 类别 (Class) ##
public class Category {
private ArrayList<MainCategory> mainCat = new ArrayList<MainCategory>();
private String name;
public void addMainCat (MainCategory name){
mainCat.add(name);
}
public ArrayList<MainCategory> returnList() {
return mainCat;
}
public void removeCat(int location){
System.out.println("The Main Category " + mainCat.get(location).getName() + " has been deleted.");
mainCat.remove(location);
}
public void removeCat(MainCategory name){
mainCat.remove(name);
}
}
## 主类别 (Class) ##
public class MainCategory{
private ArrayList<SubCategory> subCat = new ArrayList<SubCategory>();
private String name;
public void addSubCat(SubCategory name){
subCat.add(name);
}
public void removeSubCat(SubCategory name){
subCat.remove(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<SubCategory> returnList(){
return subCat;
}
}
## 子类别 (Class) ##
public class SubCategory{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
## 主要(方法)##
public static void main(String[] args) {
Category stats = new Category();
MainCategory mc1 = new MainCategory();
MainCategory mc2 = new MainCategory();
SubCategory sc1 = new SubCategory();
SubCategory sc2 = new SubCategory();
stats.addMainCat(mc1);
stats.addMainCat(mc2);
mc1.setName("salary");
mc1.addSubCat(sc1);
mc1.addSubCat(sc2);
sc1.setName("mean");
sc2.setName("median");
System.out.println(stats.returnList().get(0).getName());
System.out.println(mc1.returnList().get(0).getName());
stats.removeCat(mc1); // This one is OK.
System.out.println(stats.returnList().get(0).getName()); // Returns null, GOOD!
System.out.println(mc1.returnList().get(0).getName()); // Returns mean (it should return null because mc1 was deleted)
}
您仍有对 mc1 的引用,因此无法删除。您调用了一个您在 main class 中创建的实例,因此您只从列表中删除了一个引用,而不是类别 class 中的整个对象。
你的代码不是在做你/想要/它做的事情,而是在做你/告诉/它要做的事情。而且您没有删除类别 mc1
,您从 stats
.
中删除了 mc1
引用的类别
这意味着您在代码中创建了实例 mc1
和 stats
:
Category stats = new Category();
MainCategory mc1 = new MainCategory();
然后您将 mc1
添加到 stats
:
stats.addMainCat(mc1);
然后从 stats
:
中删除 mc1
引用
stats.removeCat(mc1); // This one is OK.
其中:
mainCat.remove(location);
实际上正在从 mainCat
列表中删除引用 location
。
但是在 main()
中你仍然有对 mc1
的引用,它仍然在你的记忆中,你仍然可以操作它。
所以你实际上没有任何问题,mc1
仍然是你在将它添加到 stats
之前实例化的对象,并且会一直存在,直到你通过执行 mc1 = null;
,然后在某个时候它会完全被垃圾收集器摧毁。
那么,在你最后两行的 main()
中,你的评论是错误的:
System.out.println(stats.returnList().get(0).getName()); // Returns null, GOOD!
System.out.println(mc1.returnList().get(0).getName()); // Returns mean (it should return null because mc1 was deleted)
第一个实际上是returnsmc2
的值,恰好是null
,因为你没有给它起名字。然后,第二个 returns 的意思是,因为它仍然是您在 main()
函数中使用的同一个 mc1
对象,无论您对 stats
做了什么。
The problem that I am having is that when I delete one of my Main Category objects (using .remove) the Sub Categories under it remain and get shifted to the next Main Category
所以你错了。子类别不会转移到下一个类别,只要 mc1
仍被引用,子类别将与类别实例一起保持实例化。一旦您取消引用它们(例如 mc1 = null
),因为您将无法查看它们,它们也会从 JVM 的内存中消失。
您应该阅读更多关于 java 如何处理实例和对实例的引用,不要再怀疑这个了!
对照:
- The difference between Classes, Objects, and Instances
- https://alfredjava.wordpress.com/2008/07/08/class-vs-object-vs-instance/
- http://heather.cs.ucdavis.edu/~matloff/Java/JavaIntro.html#tth_sEc4.4
作为一些在线资源来巩固您对 Java 的了解!
HTH
您只是从顶部列表中删除了主类别的引用,但主类别仍然是一个包含更多元素的独立列表作为子列表。你应该手动将它们删除为
mc1.returnList().clear();
我有三个 类 正在使用。 1)Category
2)MainCategory
3)SubCategory
Category
:负责creating/removing个主要类别MainCategory
:负责 creating/removing 个子类别(并将它们嵌套在各自的主类别下)SubCategory
:Sets/gets自己实例的名称
我遇到的问题是,当我删除一个主要类别对象(使用 .remove)时,它下面的子类别仍然存在并转移到下一个主要类别。我真的希望它们一起被删除,以防它们的(父)类别被删除。我在 post 末尾的 Main 方法中的注释中指出了问题。谢谢。
## 类别 (Class) ##
public class Category {
private ArrayList<MainCategory> mainCat = new ArrayList<MainCategory>();
private String name;
public void addMainCat (MainCategory name){
mainCat.add(name);
}
public ArrayList<MainCategory> returnList() {
return mainCat;
}
public void removeCat(int location){
System.out.println("The Main Category " + mainCat.get(location).getName() + " has been deleted.");
mainCat.remove(location);
}
public void removeCat(MainCategory name){
mainCat.remove(name);
}
}
## 主类别 (Class) ##
public class MainCategory{
private ArrayList<SubCategory> subCat = new ArrayList<SubCategory>();
private String name;
public void addSubCat(SubCategory name){
subCat.add(name);
}
public void removeSubCat(SubCategory name){
subCat.remove(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<SubCategory> returnList(){
return subCat;
}
}
## 子类别 (Class) ##
public class SubCategory{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
## 主要(方法)##
public static void main(String[] args) {
Category stats = new Category();
MainCategory mc1 = new MainCategory();
MainCategory mc2 = new MainCategory();
SubCategory sc1 = new SubCategory();
SubCategory sc2 = new SubCategory();
stats.addMainCat(mc1);
stats.addMainCat(mc2);
mc1.setName("salary");
mc1.addSubCat(sc1);
mc1.addSubCat(sc2);
sc1.setName("mean");
sc2.setName("median");
System.out.println(stats.returnList().get(0).getName());
System.out.println(mc1.returnList().get(0).getName());
stats.removeCat(mc1); // This one is OK.
System.out.println(stats.returnList().get(0).getName()); // Returns null, GOOD!
System.out.println(mc1.returnList().get(0).getName()); // Returns mean (it should return null because mc1 was deleted)
}
您仍有对 mc1 的引用,因此无法删除。您调用了一个您在 main class 中创建的实例,因此您只从列表中删除了一个引用,而不是类别 class 中的整个对象。
你的代码不是在做你/想要/它做的事情,而是在做你/告诉/它要做的事情。而且您没有删除类别 mc1
,您从 stats
.
mc1
引用的类别
这意味着您在代码中创建了实例 mc1
和 stats
:
Category stats = new Category();
MainCategory mc1 = new MainCategory();
然后您将 mc1
添加到 stats
:
stats.addMainCat(mc1);
然后从 stats
:
mc1
引用
stats.removeCat(mc1); // This one is OK.
其中:
mainCat.remove(location);
实际上正在从 mainCat
列表中删除引用 location
。
但是在 main()
中你仍然有对 mc1
的引用,它仍然在你的记忆中,你仍然可以操作它。
所以你实际上没有任何问题,mc1
仍然是你在将它添加到 stats
之前实例化的对象,并且会一直存在,直到你通过执行 mc1 = null;
,然后在某个时候它会完全被垃圾收集器摧毁。
那么,在你最后两行的 main()
中,你的评论是错误的:
System.out.println(stats.returnList().get(0).getName()); // Returns null, GOOD!
System.out.println(mc1.returnList().get(0).getName()); // Returns mean (it should return null because mc1 was deleted)
第一个实际上是returnsmc2
的值,恰好是null
,因为你没有给它起名字。然后,第二个 returns 的意思是,因为它仍然是您在 main()
函数中使用的同一个 mc1
对象,无论您对 stats
做了什么。
The problem that I am having is that when I delete one of my Main Category objects (using .remove) the Sub Categories under it remain and get shifted to the next Main Category
所以你错了。子类别不会转移到下一个类别,只要 mc1
仍被引用,子类别将与类别实例一起保持实例化。一旦您取消引用它们(例如 mc1 = null
),因为您将无法查看它们,它们也会从 JVM 的内存中消失。
您应该阅读更多关于 java 如何处理实例和对实例的引用,不要再怀疑这个了!
对照:
- The difference between Classes, Objects, and Instances
- https://alfredjava.wordpress.com/2008/07/08/class-vs-object-vs-instance/
- http://heather.cs.ucdavis.edu/~matloff/Java/JavaIntro.html#tth_sEc4.4
作为一些在线资源来巩固您对 Java 的了解!
HTH
您只是从顶部列表中删除了主类别的引用,但主类别仍然是一个包含更多元素的独立列表作为子列表。你应该手动将它们删除为
mc1.returnList().clear();