我正在努力通过以下代码和测试用例。但是由于从Link.java文件进行递归调用而导致堆栈溢出错误。
我已经尝试增加JVM的堆栈大小,这是堆栈溢出中的一些提示所建议的,但这无济于事。
有人可以给我一些解决方案来解决LinkTest.java文件中的所有测试用例吗?
Link.java
public class Link {
private HashSet<Link> links = new HashSet<Link>();
public void linkTo(Link link) {
links.add(link);
}
public Boolean isLinkedTo(Link to) {
Link link;
while (!links.isEmpty()) {
link = links.iterator().next();
if (link == to || link.isLinkedTo(to) == true) {
if (link == to) {
return true;
} else if (link != to && link.isLinkedTo(to) == true) {
return true;
} else if (link != to && link.isLinkedTo(to) == false) {
return false;
} else {
return true;
}
} else if (link != to || link.isLinkedTo(to) == false) {
if (link == to) {
return true;
} else if (link.isLinkedTo(to) == true) {
return true;
} else {
return false;
}
} else {
return true;
}
}
return false;
}
}
LinkTest.java
public class LinkTest extends TestCase
{
@org.junit.Test
public void testItCanLinkToItself()
{
Link foo = new Link();
foo.linkTo(foo);
assertTrue(foo.isLinkedTo(foo));
}
public void testItDoesNotLinkToItself()
{
Link foo = new Link();
assertFalse(foo.isLinkedTo(foo));
}
public void testUnidirectionalLinkToNeighbour()
{
Link foo = new Link();
Link bar = new Link();
bar.linkTo(foo);
assertTrue(bar.isLinkedTo(foo));
assertFalse(foo.isLinkedTo(bar));
}
public void testNeighboursWithConnectionsToThemselves()
{
Link foo = new Link();
Link bar = new Link();
Link baz = new Link();
// Connect the Objs to themselves.
foo.linkTo(foo);
bar.linkTo(bar);
baz.linkTo(baz);
// Connect baz => bar => foo.
baz.linkTo(bar);
bar.linkTo(foo);
assertTrue(baz.isLinkedTo(foo));
assertTrue(baz.isLinkedTo(bar));
assertTrue(bar.isLinkedTo(foo));
assertFalse(bar.isLinkedTo(baz));
}
public void testCyclicGraph()
{
Link foo = new Link();
Link bar = new Link();
Link baz = new Link();
// Connect the nodes baz => bar => foo => baz.
baz.linkTo(bar);
bar.linkTo(foo);
foo.linkTo(baz);
assertTrue(baz.isLinkedTo(foo));
assertTrue(baz.isLinkedTo(bar));
assertTrue(baz.isLinkedTo(baz));
}
public void testItCanHaveNeighboursInCyclicGraph()
{
Link foo = new Link();
Link bar = new Link();
Link baz = new Link();
// Connect the nodes baz => bar <=> foo.
baz.linkTo(bar);
bar.linkTo(foo);
foo.linkTo(bar);
assertTrue(baz.isLinkedTo(foo));
assertTrue(baz.isLinkedTo(bar));
assertFalse(baz.isLinkedTo(baz));
}
public void testCanHaveACycleOfMoreThanTwo()
{
Link foo = new Link();
Link bar = new Link();
Link baz = new Link();
Link qux = new Link();
// Connect the nodes baz => bar => foo => qux => bar.
baz.linkTo(bar);
bar.linkTo(foo);
foo.linkTo(qux);
qux.linkTo(bar);
assertFalse(qux.isLinkedTo(baz));
assertTrue(baz.isLinkedTo(foo));
assertTrue(baz.isLinkedTo(bar));
assertTrue(baz.isLinkedTo(qux));
assertFalse(baz.isLinkedTo(baz));
}
}
答案 0 :(得分:0)
我相信这将如您的测试所述。
public boolean isLinkedTo(Link to) {
// start recursion with no currently checked links
return isLinkedTo(to, new HashSet<>());
}
private boolean isLinkedTo(Link to, Set<Link> linksChecked) {
// this link is linked to 'to'
if (links.contains(to)) {
return true;
}
// this link not linked to 'to' so add it to the checked links
linksChecked.add(this);
// check all links to see if the links are linked to 'to'
for (Link link: links) {
// current link not checked yet and current link is linked to 'to'
if (!linksChecked.contains(link) && link.isLinkedTo(to, linksChecked)) {
return true;
}
}
// no links or sub-links are linked to 'to'
return false;
}
要递归地检查自链接链接而没有无限递归,则必须跟踪已检查的链接,以避免无限地检查相同的链接。这就是为什么我添加了一个辅助方法来跟踪选中的链接的原因。
正如Elliott的上面的评论所述,当使用对象的哈希集时,您想要覆盖类的equals和hashcode方法以确保哈希集按预期工作。多数情况下,仅作为附注,大多数ide都可以自动为您的类生成有效的equals哈希码。