How to write the best possible Java code for a similar Ruby functionality?

Mahendran

I have some experience in Java and I am learning Ruby. I encountered a ruby program as below:

class Tree
  attr_accessor :children, :node_name
  def initialize(name, children=[])
    @children = children
    @node_name = name
  end
  def visit_all(&block)
    visit &block
    children.each {|c| c.visit_all &block}
  end
  def visit(&block)
    block.call self
  end
end
ruby_tree = Tree.new( "Ruby" ,
                      [Tree.new("Reia" ),
                       Tree.new("MacRuby" )] )
puts "Visiting a node"
ruby_tree.visit {|node| puts node.node_name}
puts
puts "visiting entire tree"
ruby_tree.visit_all {|node| puts node.node_name}

When I looked at the power of ruby language, I thought to write similar code in Java as below:

public class Tree {

    private String name;
    private Tree[] children;

    Tree(String name, Tree[] children) {
        this.name = name;
        this.children = children;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Tree[] getChildren() {
        return children;
    }

    public void setChildren(Tree[] children) {
        this.children = children;
    }

    public static void main(String[] args) {
        Tree myTree = new Tree("Ruby", new Tree[] {
                new Tree("Reia", new Tree[] {}),
                new Tree("MacRuby", new Tree[] {}) });
        myTree.visit();
        myTree.visit_all();
    }

    public void visit() {
        System.out.println(getName());
    }

    public void visit_all() {
        visit();
        for (Tree tree : children) {
            tree.visit();
        }
    }
}

Question: I know that the java version here is not much flexible as Ruby.Is there anything similar in Java that I can do to achieve the level of flexibility like ruby does provides?

Jörg W Mittag

First, a word of caution: that code is absolutely horrible. It provides almost no encapsulation, it leaks implementation details left and right, there's no way that a Tree object can maintain its own invariants or state. Secondly, it doesn't integrate at all with Ruby's collection framework.

As a consequence, my Java translation is also equally horrible, and it also doesn't integrate with Java's collection framework.

The two biggest drawbacks that your Java code has compared to your Ruby are

  • in the Java version, the element type is hard-coded to String, whereas in the Ruby version, it can be any object, and even a mixture of objects within the same tree, and
  • in the Java version, the iterators are hard-coded to printing the name(s), whereas in the Ruby version, the iterators take a block argument with the code to execute.

The first problem cannot be easily solved in Java. You can make the collection generic, so that it can hold elements of any type, but making it heterogeneous (i.e. being able to hold elements of different types in the same collection) is going to be a lot of work. So, I stuck with the partial solution: making the Tree generic.

The second problem can be solved by having the iterators take an object which contains the code. After all, a first-class subroutine is basically the same as an object with only one method. (Java 8 is going to take some of that pain away, I included examples in the code.)

import java.util.Collection;
import java.util.ArrayList;

interface Consumer<T> {
    void accept(T e);
}
// In Java 8, this interface is already part of the JRE.
// Just replace the 3 lines above with this import:
//import java.util.function.Consumer;

class Tree<T> {
    private String nodeName;
    private Collection<Tree<T>> children = new ArrayList<>();

    Tree(String name, Collection<Tree<T>> children) {
        nodeName = name;
        this.children = children;
    }

    Tree(String name) {
        nodeName = name;
    }

    public String getNodeName() { return nodeName; }
    public void setNodeName(String name) { nodeName = name; }

    public Collection<Tree<T>> getChildren() { return children; }
    public void setChildren(Collection<Tree<T>> children) { this.children = children; }

    void visitAll(Consumer<Tree<T>> block) {
        visit(block);
        for (Tree<T> tree : children) tree.visitAll(block);
    }

    void visit(Consumer<Tree<T>> block) {
        block.accept(this);
    }

    public static void main(String... args) {
        ArrayList<Tree<String>> children = new ArrayList<>();
        children.add(new Tree<String>("Reia"));
        children.add(new Tree<String>("MacRuby"));
        Tree<String> rubyTree = new Tree<>("Ruby", children);

        System.out.println("Visiting a node");
        rubyTree.visit(new Consumer<Tree<String>>() {
            public void accept(Tree<String> node) {
                System.out.println(node.getNodeName());
            }
        });
        // In Java 8, you can use a lambda.
        // Just replace the 5 lines above with this line:
        //rubyTree.visit(node -> System.out.println(node.getNodeName()));

        System.out.println();

        System.out.println("Visiting entire tree");
        rubyTree.visitAll(new Consumer<Tree<String>>() {
            public void accept(Tree<String> node) {
                System.out.println(node.getNodeName());
            }
        });
        // In Java 8, you can use a lambda.
        // Just replace the 5 lines above with this line:
        //rubyTree.visitAll(node -> System.out.println(node.getNodeName()));
    }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Looking for similar functionality in java

How to write the similar code in PHP Laravel?

How to write similar Retrofilt code for OKHTTP format?

How to write this code better and to be similar? Javascript

Similar functionality for java to struct for python

How to write file checking code for best performance

How to best implement this Ruby code in Python

Possible way to write below code in java 8

Is it possible to write java code in build.gradle?

How to best test Java code?

How to write ruby code in option of image tag?

How to avoid write similar code multiple times in this situation?

How to write a code in R to sort the values of a column for the similar row values?

How can I write a method or a for loop for very similar code pieces

How to write an algorithm which finds the best possible event distribution?

How to write efficient Java code?

how to write the java code into matlab?

How to write Java code into JavaScript

How to achieve buffer of nodejs similar functionality in dart

Code review: what will be best possible way for the solution of this java program?

Is it possible to create an RPZ (or similar functionality) with Google Cloud DNS?

Write ruby code in string

How to extend java functionality of an abstract class without duplicating code?

How to write to Excel using MVC and EF Code First - Best Practices

Is it possible to get inline evaluation similar to Clojure in Ruby?

How to write a function similar to split()

How can I write javascript like this ruby code (array matching)?

How to use an interface/something similar to clean up duplicate code in Java

Smarter way to write similar line of code

TOP Ranking

HotTag

Archive