Changing data in linkedlist java - java

I am trying to change the data portion of a node, but I am getting a cannot find symbol error on my sets and gets for the WordItem class. The first part is the object class and the containsWord is in the LinkedList class. Any help would be appreciated.
public class WordItem implements Comparable {
private String word;
private int count;
private ArrayList<Integer> atLines;
public WordItem(String word, int c, int atLine) {
this.word = word;
this.count = c;
this.atLines = new ArrayList<Integer>();
atLines.add(atLine);
}
#Override
public int compareTo(Object other) {
WordItem w = (WordItem)other;
return w.getWord().compareTo(this.word);
}
public String getWord() {
return this.word;
}
public int getCount() {
return this.count;
}
public void setCount(int count){
this.count = count;
}
public void setAtLines(int line){
this.atLines.add(line);
}
public boolean containWord(String word, int atLine){
Node curr,prev;
boolean flag = false;
prev = head;
for(curr = head.next; curr != null; curr = curr.next){
if(word.equals(curr.data.getWord())){
ArrayList<Integer> ara = curr.data.getLines();
for(int i = 0; i < ara.size(); i++){
if(ara.get(i) == atLine){
curr.data.setCount(curr.data.getCount() + 1);
return true;
}
}
curr.data.setAtLines(atLine);
curr.data.setCount(curr.data.getCount() + 1);
return true;
}
prev = curr;
}
return false;
}

I don't see any problems in the code. I ran it and I can't reproduce the error.
It might be that your IDE got stuck. Try to Clean/Build and if that doesn't help try resetting/clearing the cache (google for that, how to do that is different with every IDE).

From the code you have posted, there is no method WordItem#getLines().
I assume that you may have just not copied all the code in your question, but just to make sure that you do have this method within your WordItem class
public ArrayList<Integer> getLines(){
return atLines;
}
If not then the following line
ArrayList<Integer> ara = curr.data.getLines();
will fail.

I think you maybe have a little typo somewhere, if you see the definition of the error: http://java.about.com/od/cerrmsg/g/Definition-Cannot-Find-Symbol.htm
That may be the problem

Related

Java Iterable<Node> inheritance

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.

In java, can nested class object use the enclosing class method?

I created a simple list class. What I want to do is to create a method in SLList to give the size a SLList object. I want to do it recursively, however, the following size() method I created just does not work. I know other ways to realize it such as creating a helper method. But what I am curious about is that why does my size() does not work? The error message is the "size() is undefined for SLList.IntNode". Why? Since I made the nested IntMode class just public and non-static, why it cannot use the method that is defined in SLList class?
public class SLList {
public class IntNode {
public int item;
public IntNode next;
public IntNode(int i, IntNode n) {
item = i;
next = n;
}
}
private IntNode first;
public SLList(int x) {
first = new IntNode(x, null);
}
public int size() {
if (first.next == null) {
return 1;
}
return 1 + first.next.size();
}
}
I am just new to Java, and quite confused about the private and static things, especially when it comes to the Class. Thank you for anyone answering me.
You can fiddle it by adding an extra private method but it's not particularly easy to reason about. I would avoid doing it this way unless absolutely necessary.
class SLList {
public class IntNode {
public int item;
public IntNode next;
public IntNode(int i, IntNode n) {
item = i;
next = n;
}
private int theSize()
{
return size();
}
}
private IntNode first;
public SLList(int x) {
first = new IntNode(x, null);
}
public int size() {
if (first.next == null) {
return 1;
}
return 1 + first.next.theSize();
}
}
Reason is : your method size() is in class SLList.
Hence it cannot be accessed by nested inner class IntNode.
size() is a method of SLList, not IntNode. You can refer to outer class method inside IntNode as follows:
public class SLList {
public class IntNode {
...
public int size() {
return SLList.this.size();
}
}
...
public static int size() {
...
}
}
Add a size method to IntNode class and access it from SLList size method to calculate the entire size of the list. The following code snippet is self explanatory. For more information about nested classes refer https://www.programiz.com/java-programming/nested-inner-class
public class SLList {
public class IntNode {
public int item;
public IntNode next;
public IntNode(int i, IntNode n) {
item = i;
next = n;
}
public int size() {
IntNode tmp = next;
if (tmp == null) {
return 1;
}
return 1 + tmp.size();
}
}
private IntNode first;
public SLList(int x) {
first = new IntNode(x, null);
}
public int size() {
if (first == null)
return 0;
return first.size();
}
public static void main(String[] args) {
SLList list = new SLList(10);
list.first.next = list.new IntNode(20, null);
list.first.next.next = list.new IntNode(30, null);
list.first.next.next.next = list.new IntNode(40, null);
System.out.println(list.size());
}
}

Troubles with java generics and linked lists/ques

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;
}
}
}

Repeated error in LinkedList

.. and by repeated, I mean repeated. I have a simple implementation of a list interface, functioning like a simple baby-version of the LinkedList.
I have the classes "Knoten"(means "knot" in German), MyLinkedList and, well, Main.
The Error my compiler tosses at me originates in class Knoten, line 35.
But it doesn´t tell me what kind of error it is.
"at Knoten.nextN(Knoten.java:35)"
is all it says. A million times. My whole cmd window is filled with this line. I bet it printed this error message for more than hundred times, again and again. I tried to search for similar problems, but couldn´t really find anything useful because I don´t know which error to search for.
Why did my program crash?
Please help..
Knoten:
class Knoten<T> {
Knoten nachfolger;
T t;
public Knoten(T t){
this.t = t;
nachfolger = null;
}
public void add(T tneu) {
if (nachfolger != null) {
nachfolger.add(tneu);
}
else {
Knoten kneu = new Knoten(tneu);
nachfolger = kneu;
}
}
public Knoten giveNachfolger(){
return nachfolger;
}
public T fuerIDGeben(int index, Knoten anfang) {
if(index == nextN(anfang)){
return (T) nachfolger.t;
}
return null;
}
private int nextN(Knoten k){
int i = 1;
if (nachfolger != null){
i = i+1;
nextN(nachfolger);
} else {}
return i;
} }
MyLinkedList:
class MyLinkedList<T> implements MyList<T>{
Knoten anfang;
public MyLinkedList<T>(){
anfang = null;
}
public T get(int index){
return (T) anfang.fuerIDGeben(index, anfang);
}
public void add(T t){
if(anfang != null){
anfang.add(t);
} else {
Knoten newKnoten = new Knoten(t);
anfang = newKnoten;
}
}
public MyIterator<T> iterate(){
return new MyLinkedIterator<T>();
}
private class MyLinkedIterator<T> implements MyIterator<T>{
public boolean hasNext(){
if(anfang.giveNachfolger() != null){
return true;
}
return false;
}
public T next(){
if(anfang.giveNachfolger() != null){
return (T) anfang.giveNachfolger().t;
}
return null;
}}}
import java.util.*;
And Main:
class Main{
public static void main(String[] args){
MyList<Integer> list = new MyLinkedList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list.get(0));
MyIterator<Integer> it = list.iterate();
while(it.hasNext()){
System.out.println(it.next());
}
}}
You have infinite recursion in nextN(), leading to a stack overflow.
If you look closely at the implementation of nextN(), it repeatedly calls itself with the same argument. This continues until the JVM runs out of stack, at which point you get a StackOverflowError. The stack trace at the point of the exception will mention nextN() many times.
Since you are not using k in the nextN function, it always calls itself with the same parameter and brings infinite loops.
Instead of that, you should call the nextN function with the member variable of k in order to iterate over them.
If you have a link like:
k -> k.nachfolger -> k.nachfolger.nachfolger -> ...
Then you need to change your function with this:
private int nextN(Knoten k){
if (k.nachfolger != null){
return nextN(k.nachfolger) + 1;
}
return 1;
}

Java Generic class doesn't display the objects i pass into it

I am trying to build a simple generic class that uses generic objects in java. everything compiles fine, but when i run the code, it doesn't display the objects i passed to it.
Here is my code:
public class ListDriver {
public static void main(String[] args) {
List<String> glist = new List<String>(10);
glist.add("milk");
glist.add("eggs");
System.out.println("Grocery List" + glist.toString());
}
public class List<T> {
private T[] datastore;
private int size;
private int pos;
public List(int numElements) {
size = numElements;
pos = 0;
datastore = (T[]) new Object[size];
}
public void add(T element) {
datastore[pos] = element;
}
public String toString() {
String elements = "";
for (int i = 0; i < pos; ++i) {
elements += datastore[i] + "";
}
return elements;
}
}
}
You don't increment your pos variable, so you're always adding in the same place. Try
public void add(T element) {
datastore[pos++] = element;
}
Your add method always replaces the element in position 0 (zero). You forgot to increment pos (pos++;)

Categories