Unable to add new element (node) to ArrayList
Node N = new Node(5,"Sandeep");
Node N1 = new Node(5,"qwert");
In below line I am getting null pointer exception
N.children.add(N1)
Code:
class Node {
public int val;
public String data;
public ArrayList<Node> children;
public Node(int val, String data) {
this.val = val;
this.data = data;
ArrayList<Node> children = new ArrayList<Node>();
}
}
public class Nary {
public static void main(String[] args) {
// ArrayList<Node> children = new ArrayList<Node>();
Node N = new Node(5,"Sandeep");
Node N1 = new Node(5,"qwert");
N.children.add(N1);
}
}
Change this in your code
class Node {
public int val;
public String data;
public ArrayList<Node> children;
public Node(int val, String data) {
this.val = val;
this.data = data;
this.children = new ArrayList<Node>();
}
}
In Node constructor you are creating new local attribute of children
If you change below in constructor its will works fine
this.children = new ArrayList();
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
The code didn't work as I think.I have tried to recode but still can't get the result I hope for. Here's the code:
public class Node<T> {
private List<Node<T>> children = new ArrayList<Node<T>>();
private Node<T> parent = null;
private T data = null;
private String a = "";
public Node(T data) { //used to create parent
this.data = data;
}
public Node(T data, Node<T> parent) {
this.parent = parent;
Node<T> child = new Node<T>(data);
this.parent.children.add(child);
}
public Node<T> getParent(Node<T> child){
return child.parent;
}
public List<Node<T>> getChildren() {
return children;
}
public int getSize(){
return children.size();
}
public String toString(){
for(int i=0; i<children.size();i++){
a = a + parent.children.get(i).getData()+ ",";
}
return a ;
}
public T getData() {
return data;
}
}
import java.util.List;
public class main {
public static void main(String[] args) {
Node<String> parentNode = new Node<String>("Parent");
Node<String> childNode1 = new Node<String>("Child 1", parentNode);
Node<String> childNode2 = new Node<String>("Child 2", parentNode);
List<Node<String>> ChildrenOfParents = parentNode.getChildren();
System.out.println(ChildrenOfParents.size());
System.out.println(ChildrenOfParents.toString());
}
}
After these lines of code, I wonder why ChildrenOfParents.toString() will not print out the children? Those child already added into the ChildrenOfParents right? I'm still new in java. Please guide me through the code. I wish to make a family tree without restriction of Family members(For example, father can have many sons instead of just 2 if follow binary tree). Thanks.
PS: Thanks for the answer that "this.parent.children.add(this)" makes the program works. But I wonder why "this.parent.children.add(child)" at line 12 doesn't work when the constructor with parameter is called? Isn't the parent's children variable will add the child into the list?
You need add child into parent object in the second constructor:
import java.util.ArrayList;
import java.util.List;
public class Node<T> {
private List<Node<T>> children = new ArrayList<Node<T>>();
private Node<T> parent = null;
private T data = null;
public Node(T data) { //used to create parent
this.data = data;
}
public Node(T data, Node<T> parent) {
this.parent = parent;
this.data = data;
this.parent.children.add(this);
}
public Node<T> getParent(Node<T> child) {
return child.parent;
}
public List<Node<T>> getChildren() {
return children;
}
public int getSize() {
return children.size();
}
public String toString() {
String a = "";
for (int i = 0; i < children.size(); i++) {
a = a + children.get(i).getData() + ",";
}
return a;
}
public T getData() {
return data;
}
}
public class NodeApp {
public static void main(String[] args) {
Node<String> parentNode = new Node<String>("Parent");
Node<String> childNode1 = new Node<String>("Child 1", parentNode);
Node<String> childNode2 = new Node<String>("Child 2", parentNode);
System.out.println(parentNode.getSize());
System.out.println(parentNode.toString());
}
}
I am doing lab, I viewed a lot of Java Generics example, but I cannot understand it. My goal is achieving Linked Stack. It have 2 files: IntStack.java and IntNode.java. The part of these code is:
public class IntNode {
private int element = 0;
private IntNode next = null;
public IntNode(final int data, final IntNode next) {
this.element = data;
this.next = next;
}
public class IntStack {
private IntNode top = null;
public boolean isEmpty() {
return this.top == null;
}
How to convert them to generics type? I know it should use <T>,and I write these code, it is correct or not?
public class Node<T> {
private T element;
private Node<T> next = null;
public Node(final T data,final Node next) {
this.element = data;
this.next = next;
}
}
You are close. The Node parameter of the Node constructor should also be parameterized:
public class Node<T> {
private T element;
private Node<T> next = null;
public Node(final T data,final Node<T> next) {
this.element = data;
this.next = next;
}
}
I am using the following code to convert a flat structure like:
test/test2/test3
test/test5/test2
test/test7/test5/test4
test/test7/test5/test9
into a tree like:
test
| | |
test2 test5 test7
| | |
test3 test2 test5
| |
test4 test9
The code:
import java.util.*;
class Tree
{
class Node
{
String data;
ArrayList<Node> children;
public Node(String data)
{
this.data = data;
children = new ArrayList<Node>();
}
public ArrayList<Node> getChildren()
{
return children;
}
public Node getChild(String data)
{
for(Node n : children)
if(n.data.equals(data))
return n;
return null;
}
}
private Node root;
public Tree()
{
root = new Node("");
}
public boolean isEmpty()
{
return root==null;
}
public void add(String str)
{
Node current = root;
StringTokenizer s = new StringTokenizer(str, "/");
while(s.hasMoreElements())
{
str = (String)s.nextElement();
Node child = current.getChild(str);
if(child==null)
{
current.children.add(new Node(str));
child = current.getChild(str);
}
current = child;
}
}
public void get()
{
return root;
}
}
I use the "add" function to split the above flat paths to a tree and it works nicely and I am able to navigate forward. Though, I want to be able to navigate to the Node with a given path and also when I navigate to some Node, I want to be able to trace it to the root element. For example, if I navigate from test -> test2 -> test3, I want to get the path from the root like test/test2/test3.
I am new to Trees and the topic is confusing me a bit, your help is highly appreciated.
Edit: Added a visual representation.
public class Tree {
private final Node root = new Node(null, null);
public boolean isEmpty() {
return root.children.isEmpty();
}
public void add(String path) {
Node parent = root;
for (String data : path.split("/")) {
Node node = parent.getChild(data);
if (node == null)
parent.children.add(node = new Node(data, parent));
parent = node;
}
}
public Node get(String path) {
Node parent = root;
for (String data : path.split("/")) {
Node node = parent.getChild(data);
if (node == null)
return null;
parent = node;
}
return parent;
}
public static final class Node {
private final String data;
private final Node parent;
private final List<Node> children = new LinkedList<>();
public Node(String data, Node parent) {
this.data = data;
this.parent = parent;
}
public List<Node> getChildren() {
return Collections.unmodifiableList(children);
}
public Node getChild(String data) {
for (Node node : children)
if (node.data.equals(data))
return node;
return null;
}
public String getPath() {
Deque<String> nodes = new LinkedList<>();
Node node = this;
while (node.parent != null) {
nodes.addFirst(node.data);
node = node.parent;
}
return String.join("/", nodes);
}
#Override
public String toString() {
return data;
}
}
public static void main(String... args) {
Tree tree = new Tree();
tree.add("test/test2/test3");
tree.add("test/test5/test2");
tree.add("test/test7/test5/test4");
tree.add("test/test7/test5/test9");
Node node = tree.get("test/test7/test5/test9");
String path = node.getPath();
}
}
A simple way is to keep track of the parent node, then just follow the parents up the tree from the child:
Node currentNode = ...
ArrayList<Node> path = new ArrayList<>();
while(currentNode != null){
path.add(currentNode);
currentNode = currentNode.getParent();
}
Collections.reverse(path);
So your Node class would need a new constructor:
class Node {
String data;
ArrayList<Node> children;
Node parent;
Node(Node parent, String data){
// ...
}
// ...
// Null if this is the root, else returns the parent node
public Node getParent(){ return parent; }
}
I am currently trying to write a method insertEnd that inserts a node at the end of a list, using the tail reference. As I am still learning about it, I do not know how I can approach this. If you have any suggestions or solutions, please could you let me know as it will help me greatly.
package lib;
public class LinkedList {
private Node head;
private Node tail;
public LinkedList(Node h){
head = h;
}
public Node getHead(){
return head;
}
public Node getTail(){
return tail;
}
public void setHead(Node n){
head = n;
}
public void insertEnd(Node newNode){
}
public class ListApp {
public static void main(String[] args){
Node n4 = new Node("green", null);
Node n3 = new Node("orange", n4);
Node n2 = new Node("blue", n3);
Node n1 = new Node("red", n2);
package lib;
public class Node {
private String item;
private Node nextItem;
public Node(String str, Node n){
item = str;
nextItem = n;
}
public String getItem(){
return item;
}
public void setItem(String str){
item = str;
}
public Node next(){
return nextItem;
}
public void setNext(Node n){
nextItem = n;
}
public String getHead(){
return item;
}
}
Here's one possible solution:
public void insertEnd(Node newNode){
newNode.setNext(null);
if (tail == null) {
tail = newNode;
head = newNode;
} else {
tail.setNext(newNode);
tail = newNode;
}
}
Assuming your Node, holds a reference to next,
public class Node<E>{
private E ele;
private Node<E> next;
P.S: Java already does have the LinkedList implemented for our convenience.
I have a Tree implementation but i want change ArrayList to simply array, i don't want use collection in java i just want use array but i don't know how i can replace ArrayList to simply array.
There is a code:
public class TreeNode {
private String data = null;
private List<TreeNode> children = new ArrayList<>();
int topSize;// I added it, since i know how is the size of Tree
private TreeNode[] children2 = new TreeNode[topSize];//I added it
private TreeNode parent = null;
public TreeNode(String data) {
this.data = data;
}
int i = 0;//I added it
public void addChild(TreeNode child) {
child.setParent(this);
this.children.add(child);
this.children2[i++] = child;//I added it
}
public void addChild(String data) {
TreeNode newChild = new TreeNode(data);
newChild.setParent(this);
children.add(newChild);
children2[i] = newChild;// I added it
}
public void addChildren(List<TreeNode> children) {
for (TreeNode t : children) {
t.setParent(this);
}
this.children.addAll(children);
}
public List<TreeNode> getChildren() {
return children;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
private void setParent(TreeNode parent) {
this.parent = parent;
}
public TreeNode getParent() {
return parent;
}
public static void main(String[] args) {
TreeNode root = new TreeNode("Root");
TreeNode child1 = new TreeNode("Child1");
child1.addChild("Grandchild1");
child1.addChild("Grandchild2");
TreeNode child2 = new TreeNode("Child2");
child2.addChild("Grandchild3");
root.addChild(child1);
root.addChild(child2);
root.addChild("Child3");
root.addChildren(Arrays.asList(
new TreeNode("Child4"),
new TreeNode("Child5"),
new TreeNode("Child6")
));
TreeNode mainRoot = new TreeNode("MainRoot");
mainRoot.addChildren(Arrays.asList(root));
for (TreeNode node : root.getChildren()) {
System.out.println(node.getData());
}
}
}
I create TreeNode[] children2 array and add int topSize, since i know what size tree will be.But it doesn't work correctly. I want Tree without collections from java.java.lang.ArrayIndexOutOfBoundsException: 0 in children2[i] = newChild;
The topSize variable is never assigned in our code, so it has the default value: 0. This means that children2 is an empty array. That's why you get an ArrayIndexOutOfBoundsException while putting something into it.
Try to initialize topSize with some value, for example:
int topSize = 10;
After this modification, your program runs with no exceptions.