How would I go around recursively traversing and storing a directory structure? I'm writing an app to load up two folders, traverse their structure, show the differences in a GUI, and synchronize the two if prompted to do so.
Background: I get the basic principle(use a tree; if a file, append it to the calling dir, if a dir, append and recursively call the function on it), but all the implementations I found are just a little bit off from what I need, or they spit out a NullPointerException which I can't fix, as I don't understand what exactly they do. I think I'm stuck on a technicality or a quirk somewhere in the recursive calls or in creating child nodes.
Edit:
This is a node class i copied from somewhere. I recently deleted my old putIntoTree function, and I'm currently working on a new one. I'm stuck on how exactly the children/parent creation works.
import java.nio.file.Path;
import java.util.*;
abstract class TreeNode implements Iterable<TreeNode> {
private Set<TreeNode> children;
public Path path;
public TreeNode(Path path) {
children = new HashSet<TreeNode>();
this.path = path;
}
public boolean addChild(TreeNode n) {
return children.add(n);
}
public boolean removeChild(TreeNode n) {
return children.remove(n);
}
public Iterator<TreeNode> iterator() {
return children.iterator();
}
}
Edit: I'm trying to get this tree structure to work in there, but I'm a bit baffled at how exactly pointy brackets and generics work. It says "cannot resolve symbol[whatever is after the in my own attempt at defining a method]"
public class Tree<T> {
private Node<T> root;
public Tree(T rootData) {
root = new Node<T>();
root.data = rootData;
root.children = new ArrayList<Node<T>>();
}
public static class Node<T> {
private T data;
private Node<T> parent;
private List<Node<T>> children;
}
}
Related
I have the class:
public class Node
{
private String id;
private List<Node> children;
}
I need to create a deep copy of a List of it List, but given that there might circular references I was trying implementing the Cloneable interface and overriding the clone method but I keep getting Stackoverflow exception, so I wonder if there is a way to deep copy it that's fast and removes the circular dependencies in the process?
Class using cloneable, when I try to clone and it has circular references I get the error mention about
public class Node implements Cloneable
{
private String id;
private List<Node> children;
#Override
public Object clone() throws CloneNotSupportedException {
Node clone = (Node) super.clone();
if (children != null) {
List<Node> cloneChildren = new ArrayList<>(children.size());
for (Node child : children) {
cloneChildren.add((Node) child.clone());
}
clone.setChildren(cloneChildren);
}
return clone;
}
public List<Node> getChildren() {
return children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
}
The easiest approach is to use an IdentityHashMap<Node,Node> to keep track of previously seen Nodes, mapping Nodes to be copied with Nodes copied thus far.
public Node copy() {
Map<Node,Node> copied = new IdentityHashMap<>();
return copy(copied, this);
}
private static Node copy(Map<Node,Node> copied, Node orig) {
Node existing = copied.get(orig);
if (existing != null) {
return existing;
}
Node copy = new Node();
copy.id = orig.id;
copy.children = new ArrayList<>();
copied.put(orig, copy);
for (Node child : orig.children) {
copy.children.add(copy(copied, child));
}
return copy;
}
(As usual, code compiled but not tested.)
I was thinking there is a 'clever' approach using Floyd's Tortoise and Hare Algorithm, but this is complicated by it not being a singly-linked list.
Working on an assignment. Taking classes online and I've emailed my prof with the same question but I'm hoping to get a quicker response from you wonderful people here (as I only have 2 hours per day that I can work on school and Ive hit a roadblock).
Assignment is to finish the code for a binary search tree and blah blah implement some stuff.
I'm hung up on one chunk of code that I just cant understand.
This is a code snippet from the LinkedBinaryTree class that was provided.
LinkedBinaryTree relies on a BinaryTreeNode class for the nodes.
public class LinkedBinaryTree<T> implements BinaryTreeADT<T>, Iterable<T>
{
protected BinaryTreeNode<T> root;
protected int modCount;
}
//Constructors
public LinkedBinaryTree()
{
root = null;
}
public LinkedBinaryTree(T element)
{
root = new BinaryTreeNode<T>(element);
}
public LinkedBinaryTree(T element, LinkedBinaryTree<T> left,
LinkedBinaryTree<T> right)
{
root = new BinaryTreeNode<T>(element);
root.setLeft(left.root);
root.setRight(right.root);
}
This is primarily what I fail to grasp.
root.setLeft(left.root);
root.setRight(right.root);
What is .root and how does that work.
The variable is being used in two places? is this some kind of recursion/magic that I just haven't encountered yet? (And currently fail to understand) If so, I will get reading let me know and point me in the right direction.
I will post the code for the BinaryTreeNode methods below. I don't understand these parameters that are being passed.
root is a variable of the type BinaryTreeNode but in its use it is passing a LinkedBinaryTree either left or right as the parameters for a method that requires a variable of type BinaryTreeNode
public class BinaryTreeNode<T>{
protected T element;
protected BinaryTreeNode<T> left, right;
//Constructors
public BinaryTreeNode(T obj)
{
element = obj;
left = null;
right = null;
}
public BinaryTreeNode(T obj, LinkedBinaryTree<T> left, LinkedBinaryTree<T> right)
{
element = obj;
if (left == null)
this.left = null;
else
this.left = left.getRootNode();
if (right == null)
this.right = null;
else
this.right = right.getRootNode();
}
And the methods in question
public void setLeft(BinaryTreeNode<T> node)
{
left = node;
}
public void setRight(BinaryTreeNode<T> node)
{
right = node;
}
This is a binary tree, as mentioned.
Every not-null node has a node to the left and right. Sometimes the value of nodes are null.
As explained in the comments of the question, you are calling the root variable from the type BinaryTreeNode. It would only make sense because the code was written.
I'm trying to write my own CustomLinkedList<E> to rapidly pass labs where I need to implement stacks and queues. I can pass the labs without this class (since I don't need to implement iterable at all), but I would like to grasp the concept since I'm learning java anyway.
I've got most of things running and tested now, but I couldn't make iterator to work properly yet.
The first approach was "post-increment", e.g.:
E result = current.getValue();
current = current.getNext();
return result;
which I found to be broken, because then when I reach the end of the list, I won't be able to get back. My hasNext() just checks if the current is null, thus the ability to go back is lost.
The second approach was to add dummy Node on creation, to model the beginning. It had an issue of determining if I'm at the beginning of the list, since with this approach I don't know where is the beginning until its too late.
Iterator(Node root)
{
current = new Node(null, null, root);
}
public E next()
{
//checks and stuff
current = current.getNext();
return current.getValue();
}
So, question is: is it possible to implement ListIterator<> only knowing the current element? If yes, some code scratches would be great.
EDIT:
Node:
private class Node
{
private Node prev;
private T value;
private Node next;
Node(Node prev, T value, Node next) {
this.setPrev(prev);
this.setValue(value);
this.setNext(next);
}
//getters and setters
}
CustomLinkedList<E>:
public class CustomLinkedList<T> implements Iterable<T>{
private class Node {/**/}
private class Iterator implements java.util.ListIterator<T> {
Node current;
public Iterator(Node root) //from the first approach
{
current = root;
}
//other methods
}
Node root;
int size;
//Object methods, and some basic Collection methods
}
I would do something like this:
public class CustomLinkedList<T> implements Iterable<T>{
private class Node {/**/}
private class Iterator implements ListIterator<T> {
Node next, previous;
Iterator() {
next = root;
previous = null;
}
public boolean hasNext() {
return next != null;
}
public T next() {
if ( ! hasNext()){
throw new NoSuchElementException();
}
previous = next;
next = next.getNext();
return previous;
}
public boolean hasPrevious() {
return previous != null;
}
public T previous() {
if ( ! hasPrevious() ){
throw new NoSuchElementException();
}
next = next.getPrevious();
previous = next.getPrevious();
return next;
}
}
Node root;
int size;
//Object methods, and some basic Collection methods
}
This doesn't implement the other methods of the ListIterator interface, but you get the idea. You need to think of your iterator's cursor as being in-between the previous and the next element, not on one of them. For a proper implementation, see Jorn Vernee's link.
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?
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()));
}
}
def visit(&block)
block.call self
end
is more nicely written as
def visit
yield self
end
Also, visit_all and visit would be more idiomatically written as conforming to the Enumerable module:
class Tree
include Enumerable
# ...
def each(&cb)
cb.call(#element)
children.each end |child|
child.each(&cb) if child.respond_to?(:each)
end
end
end
This way, you get various other things for free, like e.g. max... and also, everyone knows each applies a block to all elements, while they would have to dig through your API docs or your code to see that the function is called visit_all.
EDIT: a chunk removed because I'm apparently an idiot. Thanks to steenslag for setting me right.
I'm trying to make a non-binary learning tree that's a simplified version of the ID3 algorithm. To do this, I tried to use enums, because there are several references teaching enum hierarchies, but I'm having trouble with the transfer of enums to the functions I need to make the tree. I've set up everything I need for the tree as best as I could, but I'm having trouble with the initial construction of the tree.
First, I made six enums, each with their own file so I wouldn't need to write "main.enumname" everywhere. These first five enums represent car diagnostics.
public enum fuelstats {notempty, empty}
public enum lightstatus {Dim, Normal}
public enum scents {normal, gas}
public enum soundstatus {Normal, Howl, Screech, Click}
public enum turn {no, yes}
Next, I made two more enums. One for the different diagnostic results, and one for the different "topics" of car diagnostics.
public enum problems {battery, starter, solenoid, outofgas, flooding}
public enum features {lightstatus, soundstatus, fuelstats, scents, turn, problems}
I then made five data examples of different car diagnostics to be sorted in the tree.
Example example1 = new Example(lightstatus.Dim, soundstatus.Howl, turn.yes, fuelstats.notempty, scents.normal, problems.battery);
Example example2 = new Example(lightstatus.Normal, soundstatus.Screech, turn.no, fuelstats.notempty, scents.normal, problems.starter);
Example example3 = new Example(lightstatus.Normal, soundstatus.Click, turn.no, fuelstats.notempty, scents.normal, problems.solenoid);
Example example4 = new Example(lightstatus.Normal, soundstatus.Normal, turn.yes, fuelstats.empty, scents.normal, problems.outofgas);
Example example5 = new Example(lightstatus.Normal, soundstatus.Normal, turn.yes, fuelstats.notempty, scents.gas, problems.flooding);
//make an array list of Examples.
ArrayList<Example> Examples = new ArrayList<Example>();
Examples.add(example1);
Examples.add(example2);
Examples.add(example3);
Examples.add(example4);
Examples.add(example5);
I put the various car diagnostics, called Features, in an ArrayList for shuffling purposes, because they will be randomly used to build the tree.
//This ArrayList holds the Enums for shuffling purposes.
ArrayList<features> Features = new ArrayList<features>();
Features.add(features.soundstatus);
Features.add(features.lightstatus);
Features.add(features.turn);
Features.add(features.scents);
Features.add(features.fuelstats);
// Shuffle the elements in the list
Collections.shuffle(Features);
//The Features Array List is now a shuffled tree.
//We will do a single loop that will serve as our stack.
//First we take the top of the list and assign it to the root.
Tree id3 = new Tree(Features.get(0),Examples);
But how do I write a tree that:
Takes in a feature enum that makes the subject of the root match the enum, and all of the different statuses of the enum the children? For example, if soundstatus is the root, it should make four children that are Normal, Howl, Screech, and Click. That way I can match the Example sounds with the children sounds. This is my node so far.
public class Node
{
ArrayList<Node> children;
/* Constructor*/
public Node(ArrayList<Node> ExampleList)
{
this.ExampleList = ExampleList;
this.parent = parent;
this.children = children;
}
public ArrayList<Node> getChildren()
{
return children;
}
public void addChild(Node n)
{
children.add(n);
}
private ArrayList<Node> children;
Enum phrase;
private boolean isUsed;
Node parent;
public void setUsed(boolean isUsed)
{
this.isUsed = isUsed;
}
public boolean isUsed()
{
return isUsed;
}
//This method states if the node is a leaf
public boolean isLeaf()
{
if (this.getChildren() == null)
return true;
else
return false;
}
}
you can add a child class to features:
import java.util.*;
interface hasEnumChildren {
Class clazz();
}
enum fuelstats {
notempty,empty
}
enum lightstatus {
Dim,Normal
}
enum scents {
normal,gas
}
enum soundstatus {
Normal,Howl,Screech,Click
}
enum turn {
no,yes
}
enum problems {
battery,starter,solenoid,outofgas,flooding
}
enum features implements hasEnumChildren {
lightstatus(lightstatus.class),soundstatus(soundstatus.class),fuelstats(fuelstats.class),scents(scents.class),turn(turn.class),problems(problems.class);
features(Class clazz) {
this.clazz=clazz;
}
final Class clazz;
#Override public Class clazz() {
return clazz;
}
}
public class So10233099 {
public static void main(String[] args) {
System.out.println(Arrays.asList(features.lightstatus.clazz().getEnumConstants()));
}
}
I had a similar problem, building an hierarchy of enums. But in my case, an hierarchy of classes could also do the trick. In case you are interested here is a question I posted:
How to build an hierarchy tree of categories in java using enums or any other way?
Now, concerning only enum hierarchy, as you can see above, I found that this may work for you:
http://alexradzin.blogspot.hk/2010/10/hierarchical-structures-with-java-enums_05.html
In particular:
public enum OsType {
OS(null),
Windows(OS),
WindowsNT(Windows),
WindowsNTWorkstation(WindowsNT),
WindowsNTServer(WindowsNT),
Windows2000(Windows),
Windows2000Server(Windows2000),
Windows2000Workstation(Windows2000),
WindowsXp(Windows),
WindowsVista(Windows),
Windows7(Windows),
Windows95(Windows),
Windows98(Windows),
Unix(OS) {
#Override
public boolean supportsXWindows() {
return true;
}
},
Linux(Unix),
AIX(Unix),
HpUx(Unix),
SunOs(Unix),
;
private OsType parent = null;
private OsType(OsType parent) {
this.parent = parent;
}
I hope it helps!