如何处理 toString Java 方法中的递归?
How to deal with recursion in toString Java method?
我的程序结构如下:一个 class 表示一个 原子概念 本质上是一个字符串,另一个 class 由一个一般概念列表。 classes 都扩展了抽象的 class 概念 class,这意味着在列表中我可以同时拥有原子概念和任意嵌套的概念交集。
每个概念,无论是原子的还是组合的,都由 toString 方法打印出来。
粗略地说,这是基于这种上下文无关文法:
C : atom | (C and)+ C
其中C是抽象的class概念,atom是AtomicConcept而(C and) + C 是交集。
这是原子概念class:
public class AtomicConcept extends Concept{
private String atomicConceptName;
public AtomicConcept(String c) {
this.atomicConceptName = c;
}
@Override
public String toString() {
return atomicConceptName;
}
}
这是 che ConceptIntersection class:
import java.util.List;
public class ConceptIntersection extends Concept{
private List<Concept> list;
public ConceptIntersection(List<Concept> l) throws Exception {
if(l.size()>1)
{
this.list = l;
}
else
{
throw new Exception("Intersection needs at least two concepts!");
}
}
public String toString()
{
return Utils.conceptIntersection + Utils.lparen + Utils.splitConcepts(list) + Utils.rparen;
}
}
正如您在 toString 函数中看到的那样,我还创建了一个名为 splitConcepts 的方法,它接受输入的一般概念列表和 returns 一个由每个概念组成的字符串用逗号分隔的概念。
public static String splitConcepts(List<Concept> list)
{
String result = "";
for (Concept item : list) {
System.out.println(item);
result += item.toString() + comma;
}
result = result.substring(0, result.length() - 1);
return result;
}
问题出在哪里?
我在使用此函数时遇到问题,因为当我在另一个函数中调用嵌套交集时,此函数永远不会结束!
一个例子:
public static void main(String[] args) throws DLRException {
// TODO Auto-generated method stub
AtomicConcept atom = new AtomicConcept("one");
AtomicConcept at = new AtomicConcept("two");
List<Concept> list = new LinkedList<Concept>();
list.add(at);
list.add(atom);
DLRConceptIntersection intersection = new DLRConceptIntersection(list);
System.out.println(intersection); // works fine
list.add(intersection);
DLRConceptIntersection intersection2 = new DLRConceptIntersection(list);
System.out.println(intersection2); //loop never ends!
}
是解决这个问题的正确方法吗?
您有一个循环引用:
DLRConceptIntersection intersection = new DLRConceptIntersection(list);
list.add(intersection);
这导致 intersection
的列表包含对 intersection
引用的同一实例的引用,这就是 toString()
运行 进入无限递归的原因。
我假设您不打算 intersection
和 intersection2
共享相同的 List
。
如果在 DLRConceptIntersection
构造函数中创建 List
的副本,则可以避免它:
public ConceptIntersection(List<Concept> l) throws Exception {
if(l.size()>1) {
this.list = new ArrayList<>(l);
} else {
throw new Exception("Intersection needs at least two concepts!");
}
}
我的程序结构如下:一个 class 表示一个 原子概念 本质上是一个字符串,另一个 class 由一个一般概念列表。 classes 都扩展了抽象的 class 概念 class,这意味着在列表中我可以同时拥有原子概念和任意嵌套的概念交集。 每个概念,无论是原子的还是组合的,都由 toString 方法打印出来。 粗略地说,这是基于这种上下文无关文法:
C : atom | (C and)+ C
其中C是抽象的class概念,atom是AtomicConcept而(C and) + C 是交集。
这是原子概念class:
public class AtomicConcept extends Concept{
private String atomicConceptName;
public AtomicConcept(String c) {
this.atomicConceptName = c;
}
@Override
public String toString() {
return atomicConceptName;
}
}
这是 che ConceptIntersection class:
import java.util.List;
public class ConceptIntersection extends Concept{
private List<Concept> list;
public ConceptIntersection(List<Concept> l) throws Exception {
if(l.size()>1)
{
this.list = l;
}
else
{
throw new Exception("Intersection needs at least two concepts!");
}
}
public String toString()
{
return Utils.conceptIntersection + Utils.lparen + Utils.splitConcepts(list) + Utils.rparen;
}
}
正如您在 toString 函数中看到的那样,我还创建了一个名为 splitConcepts 的方法,它接受输入的一般概念列表和 returns 一个由每个概念组成的字符串用逗号分隔的概念。
public static String splitConcepts(List<Concept> list)
{
String result = "";
for (Concept item : list) {
System.out.println(item);
result += item.toString() + comma;
}
result = result.substring(0, result.length() - 1);
return result;
}
问题出在哪里? 我在使用此函数时遇到问题,因为当我在另一个函数中调用嵌套交集时,此函数永远不会结束!
一个例子:
public static void main(String[] args) throws DLRException {
// TODO Auto-generated method stub
AtomicConcept atom = new AtomicConcept("one");
AtomicConcept at = new AtomicConcept("two");
List<Concept> list = new LinkedList<Concept>();
list.add(at);
list.add(atom);
DLRConceptIntersection intersection = new DLRConceptIntersection(list);
System.out.println(intersection); // works fine
list.add(intersection);
DLRConceptIntersection intersection2 = new DLRConceptIntersection(list);
System.out.println(intersection2); //loop never ends!
}
是解决这个问题的正确方法吗?
您有一个循环引用:
DLRConceptIntersection intersection = new DLRConceptIntersection(list);
list.add(intersection);
这导致 intersection
的列表包含对 intersection
引用的同一实例的引用,这就是 toString()
运行 进入无限递归的原因。
我假设您不打算 intersection
和 intersection2
共享相同的 List
。
如果在 DLRConceptIntersection
构造函数中创建 List
的副本,则可以避免它:
public ConceptIntersection(List<Concept> l) throws Exception {
if(l.size()>1) {
this.list = new ArrayList<>(l);
} else {
throw new Exception("Intersection needs at least two concepts!");
}
}