I dont have much experience with generics at all and am trying to get the hang of using them. After getting this to work with integers im trying to get it to work using generics but i keep getting the following error
required: genericTree
found: int
reason: actual argument int cannot be converted to genericTree by method invocation conversion
where T is a type-variable:
T extends Object declared in class genericTree
genericTree.java:83: error: method add in class genericTree cannot be applied to given types;
I get what its telling me but im not sure how to fix it. ive been trying different approaches but nothing seems to work for me.
heres my full code:
import java.util.*;
class genericTree<T>{
private Node root;
public List <genericTree<T>> list;
private class Node
{
Node left;
Node right;
T data;
Node(T newData)
{
left = null;
right = null;
data = newData;
}
}
genericTree()
{
root = null;
}
public boolean breadthSearch(genericTree<T> searchValue)
{
Queue<Node> queue = new LinkedList<Node>() ;
if (this.root == null)
return false;
queue.clear();
queue.add(root);
while(!queue.isEmpty())
{
Node node = queue.remove();
System.out.print(node.data + " ");
if(node.data == searchValue)
return true;
if(node.left != null)
queue.add(node.left);
if(node.right != null)
queue.add(node.right);
}
return false;
}
public void add(genericTree<T> data)
{
list.add(data);
}
public void display()
{
display(root);
}
private void display(Node node)
{
if(node==null)
return;
display(node.left);
System.out.println(node.data + " ");
display(node.right);
}
public static void main(String[] args)
{
genericTree bst = new genericTree();
bst.add(10);
bst.add(5);
bst.add(6);
bst.add(13);
bst.add(15);
bst.add(8);
bst.add(14);
bst.add(7);
bst.add(12);
bst.add(4);
bst.breadthSearch(6);
}
}
thanks for any help
IT looks like you intended the following
public boolean breadthSearch(genericTree<T> searchValue)
to be this
public boolean breadthSearch(T searchValue)
You might also want to make sure that your genericTree<T> is a genericTree<int>
genericTree<int> bst = new genericTree<int>();
Related
Before all, here is a Minimal Working Example of my code on GitHub:
https://github.com/rmwesley/DancingLinks_MWE
I've been trying to implement the Dancing Links' algorithm by D. Knuth to solve the Exact Cover problem.
The code works. Problem is, I want to implement an Iterator.
In fact, the Iterator works for Node.java.
But not for Column.java, as I will further detail.
I've tried completely refactoring the code and doing some crazy modifications, but to no avail.
I left some of my best trials as commented lines of code.
These were the least garbagey ones.
My current design is as follows:
Given a problem matrix, I aimed at constructing the main data structure with 4-way nodes.
So first I implemented Node.java, a 4-way circularly linked data structure.
Then I extend Node.java in Column.java, which is the "backbone" of the structure.
Column elements then make up the main row.
Rows of Nodes are then linked with the rest of the structure with .addRow().
That is, new rows come below the last added row and above the column. Remember, circular.
See the schematics in D. Knuth's paper: https://arxiv.org/abs/cs/0011047.
With this, the full structure can be initialized from a given problem matrix.
"this" in Column serves as the head itself, so no elements are added above or below it.
Here is my source code:
Node.java
public class Node implements Iterable<Node> {
private Node upNode;
private Node downNode;
private Node leftNode;
private Node rightNode;
private Column column;
public Node() {
upNode = this;
downNode = this;
leftNode = this;
rightNode = this;
column = null;
}
#Override
public String toString() {
String str = this.column.getSize() + " ";
for (Node node : this){
str += node.column.getSize() + " ";
}
return str;
}
#Override
public java.util.Iterator<Node> iterator(){
Node currNode = this;
return new NodeIter(this);
}
public Column getColumn(){
return this.column;
}
public void setColumn(Column column){
this.column = column;
}
public Node getR(){
return this.rightNode;
}
public Node getD(){
return this.downNode;
}
public Node getL(){
return this.leftNode;
}
public Node getU(){
return this.upNode;
}
void removeHoriz() {
this.rightNode.leftNode = this.leftNode;
this.leftNode.rightNode = this.rightNode;
}
void removeVert() {
this.downNode.upNode = this.upNode;
this.upNode.downNode = this.downNode;
}
void restoreVert() {
this.downNode.upNode = this;
this.upNode.downNode = this;
}
void restoreHoriz() {
this.rightNode.leftNode = this;
this.leftNode.rightNode = this;
}
//Create an horizontal link between nodes
public void linkD(Node other) {
this.downNode = other;
other.upNode = this;
}
//Create a vertical link between nodes
public void linkR(Node other) {
this.rightNode = other;
other.leftNode = this;
}
void addHoriz(Node other) {
other.rightNode = this.rightNode;
other.leftNode = this;
}
void addVert(Node other) {
other.downNode = this.downNode;
other.upNode = this;
}
}
Column.java
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
//public class Column extends Node implements Iterable<Column>{
public class Column extends Node {
private int size;
private String name;
public Column() {
super();
this.setColumn(this);
size = 0;
name = new String();
}
public Column(int length) {
this();
Column currColumn = this;
for(int i = 0; i < length; i++){
currColumn.setName("" + i);
Column nextColumn = new Column();
currColumn.linkR(nextColumn);
currColumn = nextColumn;
}
currColumn.linkR(this);
}
public void addRow(int[] vector) throws Exception {
Column currColumn = this;
Node firstNode = new Node();
Node currNode = firstNode;
Node prevNode = currNode;
for(int index=0; index < vector.length; index++){
currColumn = currColumn.getR();
if(vector[index] == 0) continue;
currColumn.increment();
currColumn.getU().linkD(currNode);
currNode.linkD(currColumn);
currNode.setColumn(currColumn);
prevNode = currNode;
currNode = new Node();
prevNode.linkR(currNode);
}
currColumn = currColumn.getR();
prevNode.linkR(firstNode);
if(currColumn != this){
throw new Exception("Differ in length");
}
}
public Column(int[][] matrix) throws Exception {
this(matrix[0].length);
for(int i = 0; i < matrix.length; i++){
this.addRow(matrix[i]);
}
}
#Override
public Column getR(){
return (Column) super.getR();
}
#Override
public Column getL(){
return (Column) super.getL();
}
#Override
public String toString(){
String str = "";
//for (Column currColumn : this) str += currColumn.getSize() + " ";
for (Column currColumn = this.getR();
currColumn != this;
currColumn = currColumn.getR()){
str += currColumn.getSize() + " ";
}
return str;
}
public String getName(){
return this.name;
}
public int getSize(){
return this.size;
}
public void setSize(int size){
this.size = size;
}
public void setName(String name){
this.name = name;
}
public void increment(){
this.size++;
}
public void decrement(){
this.size--;
}
/*
#Override
public Iterator<Column> iterator(){
return new Iterator<Column>(){
private Column currNode = Column.this;
#Override
public boolean hasNext(){
return currNode.getR() != Column.this;
}
#Override
public Column next(){
if (!hasNext()) throw new NoSuchElementException();
currNode = currNode.getR();
return currNode;
}
};
}
*/
}
NodeIter.java
public class NodeIter implements java.util.Iterator<Node>{
private Node head;
private Node current;
public NodeIter(Node node){
this.head = this.current = node;
}
#Override
public boolean hasNext(){
return current.getR() != head;
}
#Override
public Node next(){
if (!hasNext()) throw new java.util.NoSuchElementException();
current = current.getR();
return current;
}
}
Commented lines give these errors when uncommented:
src/Column.java:5: error: Iterable cannot be inherited with different arguments: <Column> and <Node>
public class Column extends Node implements Iterable<Column>{
^
src/Column.java:111: error: iterator() in Column cannot implement iterator() in Iterable
public Iterator<Column> iterator(){
^
return type Iterator<Column> is not compatible with Iterator<Node>
where T is a type-variable:
T extends Object declared in interface Iterable
src/Column.java:76: error: incompatible types: Node cannot be converted to Column
for (Column currColumn : this) str += currColumn.getSize() + " ";
How do I make Column.java iterable?
I've been coding in Java recently, but without carefully considering design patterns.
So I fully believe I am suffering the consequences of bad code design.
Should I make some abstract class or make use of some Generic Type?
Like Node and Column, just so I can implement Iterable.
Am I wrong?
Does anyone have any pointers?
Tried using generics and overriding .iterator() method with different return types in Column.java.
Even tried using completely different class structures.
The Node class has an implementation of the Iterable interface in the form of one method:
#Override
public java.util.Iterator<Node> iterator(){
Node currNode = this;
return new NodeIter(this);
}
(BTW the first line of this method is not doing anything useful)
You are trying to make Node's subclass Column implement Iterable, meaning you want to add an overriding method like this:
#Override
public Iterator<Column> iterator()
Such an override which only differs in return type is not allowed in Java, hence the compilation error.
The fundamental problem is that, since Node is an Iterable, all its subclasses will also be an Iterable due to inheritance.
I guess you would like to write code like this:
for(Node n : node) {
for(Column c : n.getColumn()) {
c.increment();
}
}
Currently I think you could do this:
for(Node n : node) {
for(Node c : n.getColumn()) {
((Column) c).increment();
}
}
Where you are casting the iterand to Column in order to access Column methods.
I do think the design is weird when I read this for instance:
public Column() {
super();
this.setColumn(this);
eh? So a Column is a Node which has a column field? Seems like the design is conflicted about whether a Column is-a Node, or a Node has-a Column... I feel like your iterable problem will magically disappear once you figure that out.
EDIT: I don't fully grasp the algorithm and data structure yet (although I read a bit about it). From what I've understood I think you should create something like the following structure:
class Matrix {
Column[] columns;
Matrix(int[][] input) {
// init Columns
}
}
class Column {
String name;
int size;
Node firstNode;
}
class Node {
Node up;
Node down;
Node left;
Node right;
}
And avoid sub classing, it's usually not needed. Better to work with interfaces and collaborators.
hey I am new in the binary trees world and I am trying to compare to values to know which direction should I place the newly added node next.
for now, I tried to do CompareTo method but didn't succeed very much I am now trying to make a private method that will give me the value of the Nodes i would love some help
this is my code now I need to add to the if statement the comparing of nodes so I can proceed :
public void add(E data) {
if(root == null) {
return ;
}
if(root.getLeftSon() == null) {
root.setLeftSon((Node<E>) data);
}
else if(root.getRightSon() == null) {
root.setRightSon((Node<E>) data);
}
}
you have to use generics correctly. Parameter has to extend comparable so you can determinate how to sort it.
class BinaryTree<T extends Comparable<T>> {
Node<T> root;
public Node<T> addRecursive(Node<T> current, T value) {
if (current == null) {
return new Node<T>(value);
}
int ord = value.compareTo(current.value);
if (ord > 0) {
current.left = addRecursive(current.left, value);
} else if (ord < 0) {
current.right = addRecursive(current.right, value);
} else {
// value already exists
return current;
}
return current;
}
static class Node<T extends Comparable<T>> {
T value;
Node<T> left;
Node<T> right;
Node(T value) {
this.value = value;
right = null;
left = null;
}
}
}
When I unit test my pop and peek methods for my MyStack class, I encounter a NullPointerException relating to the getData method of my node class.
I cannot tell why and I am wondering if anyone has any ideas on how to fix it and make it so that there is not a NullPointerException. I have tried editing how the node works and how getData itself works but cannot find a solution and since cannot figure out the problem. Any help would be very much appreciated
import java.io.*;
import java.util.*;
public class MyStack<E> implements StackInterface<E>
{
public Node<E> head;
public int nodeCount = 0;
public static void main(String args[]) {
}
public E peek() {
return head.getData();
}
public E pop() {
if (nodeCount == 0) {
throw new EmptyStackException();
}
E item = head.getData();
head = head.getNext();
nodeCount--;
return item;
}
public boolean empty() {
if (head == null && nodeCount == 0) {
return true;
} else {
return false;
}
}
public void push(E data) {
Node<E> head = new Node<E>(data);
nodeCount++;
}
public int search(Object o) {
int count = 0;
Node<E> current = new Node<E>(head.getData());
while (current.getData() != o) {
current.getNext();
count++;
}
return count;
}
}
public class Node<E>
{
public E data;
public Node<E> next;
// getters and setters
public Node(E data)
{
this.data = data;
this.next = null;
}
public E getData() {
return this.data;
}
public void setData(E data) {
this.data = data;
}
public Node<E> getNext() {
return next;
}
public void setNext(Node<E> next) {
this.next = next;
}
}
One problem is in your push method. There, you are not assigning the new head to the member variable defined at class-level. An updated push method could look like this:
public void push(E data) {
Node<E> newHead = new Node<>(data);
newHead.setNext(head);
head = newHead;
nodeCount++;
}
In peek you should check if the stack is empty before trying to access getData():
public E peek() {
if (empty()) {
throw new EmptyStackException();
}
return head.getData();
}
Another NullPointerException happens in the search method where head.getData() is null for an empty stack. Furthermore, this method does not report the correct position of an item on the stack. I won't go into details in this answer as you have already asked a separate question.
I highly encourage to look into how to use a debugger to step through your code. Thereby, you can execute your program line by line and see where it is deviating from what you expect. Debugging is an essential skill as a programmer. Here are three resources:
IntelliJ IDEA Tutorial: Debug your first Java application
Eclipse Beginner’s Guide to Quick Start Debugging
Java Debugging with Eclipse - Tutorial
I am currently running into problems with java generics, linked list/ques structures and methods that should operate on them. Currently, I am trying to write generic methods that should manipulate a linked list of jobs for my school project. I have to implement basic methods, such as enque, de-que, sort-by-priority, get number of elements and so on. The element is, say, a printing job with a priority. A print que shall be implemented as a linked list of jobs. I am not allowed to use any pre-defined collection classes.
This being said, I am not getting something obvious. In the java code shown below, there are 3 classes (Job, MyPrintQue and LinkNode) and one generic interface (PrintQue). I am not importing any other classes from java.util. In the line 85 I use a curr.data.getPriority() method, but curr.data is taken here as the type Object, instead of the type Job, and therefore does have getPriority() method defined. Not sure why is that and how to fix it.
I've gone through a couple of related posts here, but have not found any remedy to my problem. Would be grateful for any input.
Here's the code:
Class Job
public class Job {
private int priority;
public Job(int i) {this.priority=i;}
public int getPriority(){return priority;}
public String toString () {return String.format("This job has priority %d", priority);}
}
Class MyPrintQue
public class ListNode<Job> {
public Job head;
public ListNode<Job> tail;
ListNode (Job j) {this.head=j;}
public Job getHead(){return head;}
public void setHead(Job j){}
}
Interface PrintQue
public interface PrintQue<Job> {
public void enque(Job j);
public void deque(ListNode<Job> n);
public void printQue();
public boolean isEmpty();
public ListNode<Job> hasTheHighestPriority();
public void sortByPriority();
}
and Class MyPrintQue
public class MyPrintQue<Job> implements PrintQue<Job>
{
//Setting up front and end elements of a print que.
private ListNode<Job> front;
private ListNode<Job> end;
private static int queLength;
//Accessors for head and tail.
public ListNode<Job> getFront(){return front;}
public ListNode<Job> getEnd(){return end;}
public void enque(Job j)
{
if (front == null && end == null)
{
front = new ListNode<Job>(j);
queLength++;
}
else if (front !=null & end == null)
{
end = new ListNode<Job>(j);
front.tail =end;
queLength++;
}
else
{
ListNode<Job> temp = new ListNode<Job>(j);
end.tail = temp;
end = temp;
queLength++;
}
}
public boolean find(ListNode<Job> n)
{
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail)
{
if (curr == n) return true;
}
return false;
}
public void deque(ListNode<Job> n)
{
if (find(n))
{
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail)
{
if (front == n) {front = n.tail;}
else if (curr.tail == n) {curr.tail=n.tail;}
}
n = null;
queLength--;
}
}
public void printQue()
{
int length=0;
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail)
{
System.out.println(curr.head);
length++;
}
System.out.println(length);
}
public boolean isEmpty(){if (front == null) return true; else return false;}
public ListNode<Job> hasTheHighestPriority()
{
ListNode<Job> temp = new ListNode<Job>(null);
int prior = 0;
for (ListNode<Job> curr = front; curr.head !=null; curr = curr.tail)
{
if (prior <= ((curr.head).getPriority()))
{
System.out.printf("Current priority is %d, top priority is %d%n", curr.head.getPriority(), prior);
temp = curr;
prior = (int)curr.head.getPriority();
}
}
return temp;
}
public void sortByPriority()
{
MyPrintQue<Job> temp = new MyPrintQue<Job>();
while(!isEmpty())
{
temp.enque(hasTheHighestPriority().head);
deque(hasTheHighestPriority());
}
front = temp.front;
}
}
The difference between your
public class MyPrintQue<Job> implements PrintQue<Job>
and
public class MyJobPrintQue implements PrintQue<Job>
is that in the first case Job is a generic type parameter, nothing to do with the class Job.
And the rewrite, there is a PrintQue of the class Job.
Instead of parameters <Job> better use <J> or whatever.
For good order "queue" is the spelling in English (for an explanation "few" also has double u).
The NullPointerException can be removed by:
if (front == n) {
front = n.tail;
} else {
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail) {
if (curr.tail == n) {
curr.tail = n.tail;
break;
}
}
}
So the task is to implement a linked-list and merge-sort which sorts linked-lists. I am fully aware that in industry I most likely won't have to implement any of these but I feel it's a good way to practice Java. Here is what I've got up to this point:
Node class:
public class Node<E extends Comparable<E>>
{
public E data;
public Node<E> next;
public Node(E data)
{
this.data = data;
next = null;
}
public void printData()
{
System.out.print(data + " ");
}
}
LinkedList class:
public class LinkedList<E extends Comparable<E>>
{
protected Node<E> root;
protected int size = 0;
public LinkedList()
{
root = null;
}
public void addBeg(E e)
{
Node<E> newNode = new Node<E>(e);
newNode.next = root;
root = newNode;
size++;
}
public Node deleteBeg()
{
Node<E> temp = root;
if(!isEmpty())
{
root = root.next;
size--;
}
return temp;
}
public void setRoot(Node<E> newRoot)
{
root = newRoot;
}
public boolean isEmpty()
{
return root == null;
}
public Node<E> getRoot()
{
return root;
}
public void printList()
{
Node<E> cur = root;
while(cur!=null)
{
cur.printData();
cur=cur.next;
}
System.out.println();
}
}
MergeSorter Class:
public class MergeSorter<E extends Comparable<E>>
{
public MergeSorter()
{
}
private void split(LinkedList<E> list, LinkedList<E> firHalf, LinkedList<E> secHalf)
{
//if 0 or only 1 elements in the list - it doesn't seem to work, however
if(list.getRoot() == null || list.getRoot().next == null)firHalf = list;
else{
Node<E> slow = list.getRoot();
Node<E> fast = list.getRoot().next;
while(fast!=null)
{
fast = fast.next;
if(fast!=null)
{
fast = fast.next;
slow = slow.next;
}
}
//If I use the following line firHalf list is empty when in the caller of this method (it's not in this method, however). Don't understand why ):
//firHalf = list;
firHalf.setRoot(list.getRoot());
secHalf.setRoot(slow.next);
slow.next = null;
}
}
private LinkedList<E> merge(LinkedList<E> a, LinkedList<E> b)
{
LinkedList<E> mergedList = new LinkedList<E>();
Node<E> dummy = new Node<E>(null);
Node<E> tail = dummy;
while(true)
{
if(a.getRoot() == null){
tail.next = b.getRoot();
break;
}
else if(b.getRoot() == null){
tail.next = a.getRoot();
break;
}
else
{
if(a.getRoot().data.compareTo(b.getRoot().data) <= 0)
{
tail.next = a.getRoot();
tail = tail.next;
a.setRoot(a.getRoot().next);
}
else
{
tail.next = b.getRoot();
tail = tail.next;
b.setRoot(b.getRoot().next);
}
tail.next = null;
}
}
mergedList.setRoot(dummy.next);
return mergedList;
}
public void mergeSort(LinkedList<E> list)
{
Node<E> root = list.getRoot();
LinkedList<E> left = new LinkedList<E>();
LinkedList<E> right = new LinkedList<E>();
if(root == null || root.next == null) return; //base case
split(list, left, right); //split
mergeSort(left);
mergeSort(right);
list = merge(left, right); // when this mergeSort returns this list should be
// referenced by the left or right variable of the
// current mergeSort call (but it isn't!)
}
}
I am fairly new to Java (coming from a C background) so I am sincerely sorry in advance if my code is utterly false. When I test the split and merge methods in the MergeSorter class independently, everything seems to work (splitting a list consisting of 0 or 1 element is not working and is driving me crazy but this is not needed for merge-sorting). The mergeSort method, however, is not working and I can't seem to figure out way. I tried to debug it myself and there's seems to be a problem when two halves are merged into one list and then the recursion returns. The newly merged list should be referenced by either the left or right variable of the current mergeSort call but instead I get only the last element instead of the whole list.
Method arguments in Java are always passed by value.
This can be a bit confusing, since objects are always accessed via references, so you might think they're passed by reference; but they're not. Rather, the references are passed by value.
What this means is, a method like this:
public void methodThatDoesNothing(Object dst, Object src) {
src = dst;
}
actually does nothing. It modifies its local variable src to refer to the same object as the local variable dst, but those are just local variables that disappear when the function returns. They're completely separate from whatever variables or expressions were passed into the method.
So, in your code, this:
firHalf = list;
does not really do anything. I guess what you want is:
while (! firHalf.isEmpty()) {
firHalf.deleteBeg();
}
if (! list.isEmpty()) {
firHalf.addBeg(list.root().data);
}
which modifies the objected referred to by firHalf so it has the same zero-or-one elements as list.