In my program, I write my own LinkedList class. And an instance, llist.
To use it in foreach loop as following, LinkedList needs to implement Iterable?
for(Node node : llist) {
System.out.print(node.getData() + " ");
}
Here following is my LinkedList class. Please let me know how can I make it Iterable?
public class LinkedList implements Iterable {
private Node head = null;
private int length = 0;
public LinkedList() {
this.head = null;
this.length = 0;
}
LinkedList (Node head) {
this.head = head;
this.length = 1;
}
LinkedList (LinkedList ll) {
this.head = ll.getHead();
this.length = ll.getLength();
}
public void appendToTail(int d) {
...
}
public void appendToTail(Node node) {
...
}
public void deleteOne(int d) {
...
}
public void deleteAll(int d){
...
}
public void display() {
...
}
public Node getHead() {
return head;
}
public void setHead(Node head) {
this.head = head;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public boolean isEmpty() {
if(this.length == 0)
return true;
return false;
}
}
Implement the only method of the Iterable interface, iterator().
You will need to return an instance of Iterator in this method. Typically this is done by creating an inner class that implements Iterator, and implementing iterator by creating an instance of that inner class and returning it.
Related
This one our first class AbstractLinkedList<T>
public abstract class AbstractLinkedList<T> {
public class Node<T> {
public T value;
Node<T> next;
public Node(T value, Node<T> next) {
this.value = value;
this.next = next;
}
}
Node<T> head;
public Node<T> getHead() {
return head;
}
public void addFirst(T value) {
head = new Node<>(value, head);
}
public void addLast(T value){
if(head==null)
head = new Node<>(value, null);
else {
Node<T> node = head;
while (node.next!=null)
node = node.next;
node.next = new Node<>(value, null);
}
}
public void print(){
System.out.println(toString());
}
#Override
public String toString(){
if(head==null) return "boş";
String r="";
Node<T> node=head;
while(node!=null) {
r += node.value + (node.next!=null?" ":"");
node=node.next;
}
return r;
}
public abstract void insertInOrder(T value);
public abstract AbstractLinkedList<T> reverse();
public abstract AbstractLinkedList<T> concatenate(AbstractLinkedList<T> list);
}
This is second one Odev1LinkedList implements Comparable<T>> extends AbstractLinkedList<T>
public class Odev1LinkedList<T extends Comparable<T>> extends AbstractLinkedList<T> {
#Override
public AbstractLinkedList<T> reverse() {
Odev1LinkedList a = new Odev1LinkedList();
Node<T> root = new Node(this, head);
Node<T> iter = root;
Node<T> temp ;
a.head = null;
do {
temp = iter;
a.addFirst(temp.value);
iter = iter.next;
}while (temp !=root );
return a;
}
When I run this code example.reverse should make reverse and return LinkedList without changing ORIGINAL LinkedList.
But its return without reversing
You can't use the < operator on arbitrary objects. It's only defined for primitive numbers. Take a look into the specification.
If your object of type T implements Comparable<T> you can use head.value.compareTo(value) < 0.
If you want your objects of type T to implement Comparable<T> you have to go to your class declaration and write
public class MyLinkedList<T extends Comparable<T>> { ... }
I have private class node inside public class singlyLinkedList and I want to move through the List (as temp) from another public class, so how I can creat temporary Node or(method) to move through the List.
and I can't change the class Node to public and I should keep to private.
the idea of programming is:
the read data from file in TextAnalyzer class, then insert it in SinglyLinkedList with counting the frequency of words.
class singlyLinkedList
public class SinglyLinkedList<T> {
private static class Node<T> {
public T data;
Node<T> next;
public Node(T data) {
this.data = data;
next = null;
}
}
Node<T> head;
Node<T> tail;
int size;
public SinglyLinkedList() {
head = null;
tail = null;
size = 0;
}
public void insert(T S) {
Node<T> temp = new Node<T>(S);
if (head == null) {
head = tail = temp;
size++;
return;
}
temp.next = head;
head = temp;
size++;
return;
}
public void display() {
Node<T> tmp = head;
while (tmp != null) {
System.out.println(tmp.data.toString());
tmp = tmp.next;
}
The class TextAnalyzer
SinglyLinkedList<WData> list = new SinglyLinkedList<WData>();
private static class WData {
String word;
int freq;
public WData(String w, int f) {
word = w;
freq = f;
}
// .. Add other methods here as needed
#Override
public String toString() {
// if(list.)
return "WData{" + "word=" + word + " , freq=" + freq + '}';
}
}
public Scanner sc;
public void processText(String filename) {
try {
sc = new Scanner(new File(filename));
while (sc.hasNext()) {
String line = sc.next();
String[] st = line.split(" ");
for (int i = 0; i < st.length; i++) {
processWord(st[i]);
}}
list.display();
} catch (FileNotFoundException ex) {
System.out.println("error in loadstudends Scanner");
}
}
public void processWord(String word) {
Node<WData> temp = list.head;
while (temp != null) {
if (temp.data.word.equalsIgnoreCase(word)) {
break;
}
temp = temp.next;
}
if (temp == null || Dtemp.data.word.matches(".*\\d.*")) {
list.insert(new WData(word, 1));
} else {
temp.data.freq += 1;
}
}}
we can't creat node temp because class node is private, so I couldn't go for the loop
You may want to do the following
1. Create your own Iterator implementation within SinglyLinkedList
public class MyIterator implements Iterator<T> {
private Node<T> next = head;
private Node<T> current = null;
#Override
public boolean hasNext() {
return next != null;
}
#Override
public T next() {
if (hasNext()) {
current = next;
next = current.next;
return current.data;
}
throw new NoSuchElementException();
}
#Override
public void remove() {
//TODO
}
}
Make SinglyLinkedList to implement Iterable
public class SinglyLinkedList<T> implements Iterable<T> {
return instance of iterator created in 1 when iterator() is invoked
#Override
public Iterator<T> iterator() {
return new MyIterator();
}
Use for each loop in your Text Analyzer class
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.
As a homework I'm creating a SingleLinkedNode class that implements a Node interface.
Node Interface
public interface Node <T> {
static final String NULL_NODE_ERROR = "Node can't be null";
public void setNextNode(Node nextNode) throws NullPointerException;
public void setIndex(int index);
public int getIndex();
public T getData();
public Node getNextNode();
}
SingleLinkedNode class
public class SingleLinkedNode<T> implements Node<T> {
private int index;
private T data;
private SingleLinkedNode nextNode;
public SingleLinkedNode() {
}
public SingleLinkedNode(int index) {
this.index = index;
}
public SingleLinkedNode(int index, SingleLinkedNode nextNode) {
this.index = index;
this.nextNode = nextNode;
}
#Override
public void setNextNode(SingleLinkedNode nextNode) throws NullPointerException{
if (nextNode == null){
throw new NullPointerException(NULL_NODE_ERROR);
}
this.nextNode = nextNode;
}
#Override
public void setIndex (int index){
this.index = index;
}
#Override
public int getIndex() {
return this.index;
}
#Override
public T getData() {
return this.data;
}
#Override
public SingleLinkedNode getNextNode() {
return this.nextNode;
}
}
In the setNextNode(SingleLinkedNode nextNode) method of the class it says that I'm not implementing the setNextNode(Node nextNode) method of the interface even though SingleLinkedNode implements Node.
But if I leave the class method exactly as the interface one it says that Node can't be converted to SingleLinkedNode, pretty obvious.
Is there any right way of overriding this method and being sure that the method only accepts SingleLinkedNode objects as arguments?
I thought about casting but I'm not sure if that the right way.
Thank you all the solution was as follows
#Override
public void setNextNode(Node nextNode) throws NullPointerException, IllegalArgumentException{
if (nextNode == null){
throw new NullPointerException(NULL_NODE_ERROR);
}
if ( ! (nextNode instanceof SingleLinkedNode) ) {
throw new IllegalArgumentException ("Node is not SingleLinkedNode");
}
this.nextNode = (SingleLinkedNode) nextNode;
}
The problem comes in the toString method of the following code:
import java.util.*;
public class LinkedDeque<T> // implements Deque<T>
{
private Node head;
private Node tail;
private int size;
private class Node // Node class
{
T info;
Node next;
Node prev;
private Node (T info, Node prev, Node next)
{
this.info = info;
this.prev = prev;
this.next = next;
}
private T getInfo()
{
return this.info;
}
private Node getNext()
{
return this.next;
}
private Node getPrev()
{
return this.prev;
}
}
public LinkedDeque ()
{
this.head = null;
this.tail = null;
this.size = 0;
}
public static void main()
{
}
public int size ()
{
Node count = head;
while(count.getNext() != null)
{
size++;
count = count.getNext();
}
return size;
}
public String toString()
{
return this.getInfo();
}
public boolean isEmpty()
{
return size() == 0;
}
}
My compiler keeps giving me an error saying that the getInfo method is missing. Any help would be appreciated! Initially, I thought this was due to the fact that the Node class was private, but the Node getNext() method works fine in the method size().
The toString method is a member of LinkedDeque not Node. LinkedDeque does not have a getInfo method.
Not sure what it is you were trying to achieve, but you may consider moving that method into the Node class...