【问题标题】:How to print out the vaule withing public void testDistanceBetween_AD如何打印出 public void testDistanceBetween_AD 中的值
【发布时间】:2016-09-07 02:17:14
【问题描述】:

我正在展示我的源代码,因为我无法在 TrainsTest 类中进行简单的系统输出打印,这让我很沮丧。如您所见,我在以下方法的 TrainsTest 类中打印值时遇到问题;

public void testDistanceBetween_ABC 公共无效 testDistanceBetween_AD 公共无效 testDistanceBetween_ADC 公共无效 testDistanceBetween_AEBCD 公共无效 testDistanceBetween_AED 公共无效numRoutesWithin_CC30 public void testEquals

任何帮助将不胜感激!谢谢!

下面是我的节点类


package com.utsavized.trains;

public class Node {
public String name;
public boolean visited;

public Node(String name) {
    this.name = name;
    this.visited = false;
}

@Override
public boolean equals(Object b) {
    if (b == null || b.getClass() != getClass()) {
        return false;
    }
    Node bx = (Node)b;
    return this.name.equals(bx.name);
}

@Override
public int hashCode() {
    if(this.name == null) return 0;
    return this.name.hashCode();
}
}

下面是我的 Edge 类


public class Edge {

public Node origin;

public Node destination;

public int weight;

public Edge next;

public Edge(Node origin, Node destination, int weight) {
    this.origin         = origin;
    this.destination    = destination;
    this.weight         = weight;
    this.next       = null;
}

public Edge next(Edge edge) {
    this.next = edge;
    return this;
}
}

下面是我的路线课


import java.util.ArrayList;
import java.util.Hashtable;

public class Routes {
public Hashtable<Node, Edge> routeTable;

public Routes() {
    this.routeTable = new Hashtable<Node, Edge>();
}


public int distanceBetween(ArrayList<Node> cities) throws Exception {
    /*There is no distance between
     * no cities or 1 city*/
    if(cities.size() < 2)
        return 0;
    int distance, depth, i;
    distance = depth = i = 0;

    /* For each city in the list,
     * we check if entry exists in our
     * hash table.
     */
    while(i < cities.size() - 1) {
        if(this.routeTable.containsKey(cities.get(i))) {
            Edge route = this.routeTable.get(cities.get(i));
            /*If key exists, we check if route from key to next
             * city exists. We add the distance, and maintain a
             * depth count
             */
            while(route != null) {
                if(route.destination.equals(cities.get(i + 1))) {
                    distance += route.weight;
                    depth++;
                    break;
                }
                route = route.next;
            }
        }
        else
            throw new Exception("NO SUCH ROUTE");
        i++;
    }
    /*If edge depth is not equal to vertex - 1,
     * then it is safe to assume that one ore more
     * routes do not exist
     */
    if(depth != cities.size() - 1)
        throw new Exception("NO SUCH ROUTE");

    return distance;
}

/*
 * Number of stops;
 * Wrapper for recursive function
 */
public int numStops(Node start, Node end, int maxStops) throws Exception{
    //Wrapper to maintain depth of traversal
    return findRoutes(start, end, 0, maxStops);
}

/*
 * Finds number of stops from start to end,
 * with a maximum of maxStops and the depth
 * limit.
 */
private int findRoutes(Node start, Node end, int depth, int maxStops) throws Exception{
    int routes = 0;
    //Check if start and end nodes exists in route table
    if(this.routeTable.containsKey(start) && this.routeTable.containsKey(end)) {
        /*
         * If start node exists then traverse all possible
         * routes and for each, check if it is destination
         * If destination, and number of stops within 
         * allowed limits, count it as possible route.
         */
        depth++;
        if(depth > maxStops)        //Check if depth level is within        limits
            return 0;
        start.visited = true;       //Mark start node as visited
        Edge edge = this.routeTable.get(start);
        while(edge != null) {
            /* If destination matches, we increment route
             * count, then continue to next node at same depth
             */
            if(edge.destination.equals(end)) {
                routes++;
                edge = edge.next;
                continue;
            }
            /* If destination does not match, and
             * destination node has not yet been visited,
             * we recursively traverse destination node
             */
            else if(!edge.destination.visited) {
                routes += findRoutes(edge.destination, end, depth,                                                        maxStops);
                depth--;
            }
            edge = edge.next;
        }
    }
    else
        throw new Exception("NO SUCH ROUTE");

    /*
     * Before exiting this recursive stack level,
     * we mark the start node as visited.
     */
    start.visited = false;
    return routes;
}

/*
 * Shortest route;
 * Wrapper for recursive function
 */
public int shortestRoute(Node start, Node end) throws Exception {
    //Wrapper to maintain weight
    return findShortestRoute(start, end, 0, 0);

}

/*
 * Finds the shortest route between two nodes
 */
private int findShortestRoute(Node start, Node end, int weight, int shortestRoute) throws Exception{
    //Check if start and end nodes exists in route table
    if(this.routeTable.containsKey(start) && this.routeTable.containsKey(end)) {
        /*
         * If start node exists then traverse all possible
         * routes and for each, check if it is destination
         */
        start.visited = true;       //Mark start node as visited
        Edge edge = this.routeTable.get(start);
        while(edge != null) {
            //If node not already visited, or is the destination, increment weight
            if(edge.destination == end || !edge.destination.visited)
                weight += edge.weight;

            /* If destination matches, we compare
             * weight of this route to shortest route
             * so far, and make appropriate switch
             */
            if(edge.destination.equals(end)) {
                if(shortestRoute == 0 || weight < shortestRoute)
                    shortestRoute = weight;
                start.visited = false;
                return shortestRoute;           //Unvisit node and return shortest route
            }
            /* If destination does not match, and
             * destination node has not yet been visited,
             * we recursively traverse destination node
             */
            else if(!edge.destination.visited) {
                shortestRoute = findShortestRoute(edge.destination, end, weight, shortestRoute);
                //Decrement weight as we backtrack
                weight -= edge.weight;
            }
            edge = edge.next;
        }
    }
    else
        throw new Exception("NO SUCH ROUTE");

    /*
     * Before exiting this recursive stack level,
     * we mark the start node as visited.
     */
    start.visited = false;
    return shortestRoute;

}

/*
 * Shortest route;
 * Wrapper for recursive function
 */
public int numRoutesWithin(Node start, Node end, int maxDistance) throws Exception {
    //Wrapper to maintain weight
    return findnumRoutesWithin(start, end, 0, maxDistance);
}

/*
 * Finds the shortest route between two nodes
 */
private int findnumRoutesWithin(Node start, Node end, int weight, int maxDistance) throws Exception{
    int routes = 0;
    //Check if start and end nodes exists in route table
    if(this.routeTable.containsKey(start) && this.routeTable.containsKey(end)) {
        /*
         * If start node exists then traverse all possible
         * routes and for each, check if it is destination
         */
        Edge edge = this.routeTable.get(start);
        while(edge != null) {
            weight += edge.weight; 
            /* If distance is under max, keep traversing
             * even if match is found until distance is > max
             */
            if(weight <= maxDistance) {
                if(edge.destination.equals(end)) {
                    routes++;
                    routes += findnumRoutesWithin(edge.destination, end, weight, maxDistance);
                    edge = edge.next;
                    continue;
                }
                else {
                    routes += findnumRoutesWithin(edge.destination, end, weight, maxDistance);
                    weight -= edge.weight;  //Decrement weight as we backtrack
                }
            }
            else 
                weight -= edge.weight;

            edge = edge.next;
        }
    }
    else
        throw new Exception("NO SUCH ROUTE");

    return routes;

}   

}

下面是我的 TrainsTest 课程


    package com.utsavized.trains;



    import static org.junit.Assert.*;

    import java.util.ArrayList;
    import java.util.stream.Collectors;

    import org.junit.BeforeClass;
    import org.junit.Test;

    public class TrainsTest {
static Routes graph;
static Node a, b, c, d, e;

@BeforeClass
public static void setUpBeforeClass() throws Exception {
    graph = new Routes(); //Build graph

    a = new Node("A");
    b = new Node("B");
    c = new Node("C");
    d = new Node("D");
    e = new Node("E");

    /*Input given in programming challenge
    Graph: AB5, BC4, CD8, DC8, DE6, AD5, CE2, EB3, AE7*/
    graph.routeTable.put(a, new Edge(a, b, 5).next(new Edge(a, d, 5).next(new Edge(a, e, 7))));
    graph.routeTable.put(b, new Edge(b, c, 4));
    graph.routeTable.put(c, new Edge(c, d, 8).next(new Edge(c, e, 2)));
    graph.routeTable.put(d, new Edge(d, c, 8).next(new Edge(d, e, 6)));
    graph.routeTable.put(e, new Edge(e, b, 3));
}

@Test
public void testDistanceBetween_ABC() throws Exception {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(b);
    route.add(c);
    //System.out.println(a);
    assertEquals(9, graph.distanceBetween(route));      

}

@Test
public void testDistanceBetween_AD() throws Exception {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(d);
    assertEquals(5, graph.distanceBetween(route));
}

@Test
public void testDistanceBetween_ADC() throws Exception  {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(d);
    route.add(c);
    assertEquals(13, graph.distanceBetween(route));
}

@Test
public void testDistanceBetween_AEBCD() throws Exception  {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(e);
    route.add(b);
    route.add(c);
    route.add(d);
    assertEquals(22, graph.distanceBetween(route));
}

@Test(expected=Exception.class)
public void testDistanceBetween_AED() throws Exception  {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(e);
    route.add(d);
    assertEquals(-1, graph.distanceBetween(route));
}

@Test
public void testNumStops_CC3() throws Exception {
    int numStops = graph.numStops(c, c, 3);
    assertEquals(2, numStops);
}

@Test
public void testNumStops_AC4() throws Exception {
    int numStops = graph.numStops(a, c, 4);
    assertEquals(4, numStops);
}

@Test
public void testShortestRoute_AC() throws Exception {
    int shortestRoute = graph.shortestRoute(a, c);
    assertEquals(9, shortestRoute);
    System.out.println(shortestRoute);  
}

@Test
public void testShortestRoute_BB() throws Exception {
    int shortestRoute = graph.shortestRoute(b, b);
    assertEquals(9, shortestRoute);
}

@Test
public void numRoutesWithin_CC30() throws Exception {
    int numRoutesWithin = graph.numRoutesWithin(c, c, 30);
    assertEquals(7, numRoutesWithin);
}

@Test
public void testEquals() {
    Node a1 = new Node("A");
    Node a2 = new Node("A");
    Node b = new Node("B");

    assertEquals(true, a1.equals(a2));
    assertEquals(false, a1.equals(b));
    assertEquals(true, (new Node("Test").equals(new Node("Test"))));
}

}

您好,我正在尝试打印 a、b 和 c 的值。如您所见,我在路由上使用 System out println 但它没有输出任何内容。有没有办法在不对方法进行过多修改的情况下输出结果?

public void testDistanceBetween_ADC() throws Exception  {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(d);
    route.add(c);
    assertEquals(13, graph.distanceBetween(route));
    System.out.println(route);
}

我不确定是否应该输出变量“路由”,或者是否需要添加另一个小方法。任何帮助都将不胜感激我知道这是我想做的一件简单的事情,但由于某种原因它对我不起作用。

非常感谢!!

【问题讨论】:

  • 测试成功了吗?万一它失败了,它会在 assertEqual 方法上结束,跳过 System.out.println ...只是为了确定
  • 测试运行成功但输出:com.utsavized.trains.Node@41 有没有办法输出这个方法?

标签: java arrays eclipse arraylist system.out


【解决方案1】:

你有 3 个选项

实现 toString()

如果 Node 类是您的源代码的一部分,只需添加 toString 方法

public String toString(){
    return name;
}

覆盖节点

如果 Node 类是外部库的一部分但不是最终类,您可以覆盖节点并实现 toString() 使用被覆盖的类,而不是像 supahupe 建议的那样。

使用流和地图进行显示

如果您无法按照 Supahupe 的建议覆盖节点,您可以使用可公开访问的 name 字段并将其映射到新的字符串列表并打印出来

System.out.println(route.stream().map(n -> n.name).collect(Collectors.toList()));

或者,您可以为您的节点创建一个装饰器类,其唯一目的是很好地打印出来,方法与流相同

...stream().map(n -> new NodeDecorator(n))...

【讨论】:

  • 你能举个例子说明使用上面的例子会是什么样子吗?
  • 你只需用我的替换你的 System.out.. 语句,就是这样。 stream.map.collect 东西将 List 转换为 List 应该是可打印的
  • 当我用你的系统替换我的系统时,它给我一个错误 - 类型节点未定义适用于此处的 getName(Node)
  • 这是一个基于假设存在这种方法的示例,可能 n -> n.name 有效
  • 谢谢,我已经提供了完整的源代码。如果您能看一看,我将不胜感激。
【解决方案2】:

在对我的原始答案进行编辑时,您的 distanceBetween 方法的内部 while 循环中似乎存在错误。

如果路由包含节点 A、B、C,它将计算节点 A,将边获取到节点 B,然后在内部循环中将边的权重相加。之后,您拨打break。这将打破两个while循环

如果你真的想打破循环,你应该看看如何在java中标记循环:Labeled Loops

我不喜欢使用标记循环,因为它有时会有点混乱。在您的情况下,只需使用:

if(route.destination.equals(cities.get(i + 1))) {
                distance += route.weight;
                depth++;
} else {
            route = route.next;
}

//do further (error) handling

目前,尚不清楚您想用深度变量做什么。在您的实现中,它总是会抛出异常,因为您在找到第一条路线后中断循环,然后总结深度,然后检查深度是否具有特定大小。所以在超过 2 个节点的路由上,这个异常总是会发生。

举个简单的例子,只处理距离可能很有用:

       //...
        Edge route = this.routeTable.get(cities.get(i));
        int newDistance = distance;
        /*If key exists, we check if route from key to next
         * city exists. We add the distance, and maintain a
         * depth count
         */
        while(route != null) {
            if(route.destination.equals(cities.get(i + 1))) {
                newDistance += route.weight;
               // depth++;
            } else {
                route = route.next;
            }
        }

        if(newDistance == distance) {
             //the distance didnt change - it seems there was no route found, throw Exception or expand the graph or whatever
        } else {
             distance = newDistance; //now you have the distance for the next loop-run
        }

【讨论】:

  • 你能举个例子说明使用上面的例子会是什么样子吗?
  • 我试过了,还是不行,这让我很沮丧。我知道我错过了一些小东西。总是这样!
  • 请显示您的节点类和图形类以及您在 toString() 方法中所做的操作
  • 包 com.utsavized.trains;公共类节点 { 公共字符串名称 = null;公共布尔访问过; int id = 0;公共节点(字符串名称,int id){ this.name = name; this.visited = false;} public boolean equals(Object b) { if (b == null || b.getClass() != getClass()) { return false;} Node bx = (Node)b; return this.name.equals(bx.name);} public int hashCode() { if(this.name == null) return 0; return this.name.hashCode();} public String toString() { return "Node: [name:"+this.name+",id:"+this.id+"]"; }}
  • 这是全班吗?因为我找不到任何似乎对计算节点之间的距离有意义的属性。您是自己编写了 Graph 及其节点,还是像 Gerald Mücke 所问的那样,它是一个外部库或类似的东西?