简体   繁体   中英

Alternative to nested loops

I wrote these method for my program and i felt that it is hard to read as there are too many loops, is there any other alternative to this code to make it look cleaner and easier to read

public static void printRoutingTable(Map <Node, List<Edge>> adj, Node Root)
{
    for (Node thisNode : adj.keySet())
    {   
        Node currentNode = thisNode;
        String nextHop;             
        if(currentNode.getParent() != null){
            do{
                if(currentNode.getParent() != Root){
                    currentNode = currentNode.getParent();
                    nextHop =  currentNode.getAddr();
                }
                else{
                   nextHop = currentNode.getAddr() ;
                }       
            }
            while(currentNode.getParent() != Root);
        }
        else
        {
            nextHop = ""+currentNode.getAddr();
        }
        nextHop = nextHop.trim();
    }
}

I've not tried, but this should be a functional and recursive version of your code.

String getNextAddr(Node node, StringBuilder sb, Node root) {
    sb.add(node.getAddr());
    if (node.getParent() != null && node.getParent() != root) {
      return getNextAddr(node.getParent(), sb);
    }
    return sb.toString();
}

String nextHopList = 
  adj.keySet()
    .stream()
    .map(k -> getNextAddr(k, new StringBuilder(), Root))
    .collect(Collectors.toList())

It's difficult to tell what your code is trying to achieve. At the moment it's not actually doing anything because the nextHop variable is local and nothing seems to be accumulated in the loop. I'm assuming you intend to join the strings your are generating.

  • there's no point passing in a map if you aren't going to use it. Better to pass a collection (or, better, Stream ) of nodes.
  • generally the root node is the only one with a null parent. So it's likely you also don't need to pass in a reference to the root node.
  • if parent is optional I suggest you return Optional<Node> from getParent rather than Node .
  • an easy way to make the code easier to read is to break the parts into separate methods that are named after exactly what they do.

So taking these suggestions into account, something like the following:

String getRoutingTable(Stream<Node> nodes) {
    return nodes
        .flatMap(this::getRoutingForNode)
        .map(Node::getAddr)
        .collect(joining(";"));
}

private Stream<Node> getRoutingForNode(Node node) {
    Stream.Builder<Node> pathToRoot = Stream.builder();
    for (Node c = node; c.getParent().isPresent(); c = node.getParent().get()) {
        pathToRoot.accept(c);
    }
    return pathToRoot.build();
}

Note that in Java 9 the getRoutingForNode will become much more readable as you will be able to dispense with the Builder :

return Stream.iterate(node, 
    n -> node.getParent().isPresent(), 
    n -> n.getParent().get());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM