read from file then create objects of private class - java

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

Related

How to create a doubly linked list of multiple data types

I am currently writing a program that creates Students and stores them in a doubly linked list based on their natural order (Last name, First name, GPA, then student ID). I am just starting off with generics and how they work so I am a little lost. I believe most of my code is working; the only part I need help with is adding students (who have multiple data types) into my list in my main method in my doubly linked list class. Any help is greatly appreciated! Here is my student, doubly linked list, and node class along with a fragment of the input file I am reading from with the data of each student:
Student class:
public class Student{
long studentID;
String firstName;
String lastName;
float GPA;
public Student(String lastName, String firstName, float GPA, long studentID){
this.lastName = lastName;
this.firstName = firstName;
this.GPA = GPA;
this.studentID = studentID;
}
public int compareTo(Student s){
int result = this.lastName.compareTo(s.lastName);
if(result == 0){
result = this.firstName.compareTo(s.firstName);
if(result == 0){
result = Float.compare(this.GPA, s.GPA);
if(result == 0){
result = Long.compare(this.studentID, s.studentID);
}
}
}
return result;
}
public String toString(){
return this.lastName + ", " + this.firstName +
" GPA: " + this.GPA + " ID: " + this.studentID;
}
}
Node class:
public class Node<T>{
Node<T> previous;
Node<T> next;
Student data;
public Node(Student data){
this(data, null, null);
}
public Node(Student data, Node<T> previous, Node<T> next){
this.data = data;
this.previous = previous;
this.next = next;
}
}
Doubly Linked List class:
import java.io.*;
import java.util.*;
import csci1140.*;
public class DoublyLinkedList<T> implements Iterable<Node>{
private Node root;
private Node tail;
private Node previous;
private class ListIterator implements Iterator<Node>{
Node current = root;
public boolean hasNext(){
return (current != null);
}
public Node next(){
Node answer;
answer = current;
current = current.next;
return answer;
}
}
public Iterator<Node> iterator(){
ListIterator listIterator = new ListIterator();
return listIterator;
}
public void add(T data){
Node<Student> newNode = new Node<Student>(data);
if(root == null){
root = newNode;
tail = root;
return;
}
Node current = root;
for( ; current!= null; current = current.next){
if(newNode.data.compareTo(current.data)<= 0){
break;
}
}
if(previous == null){
previous.next = newNode;
newNode.next = current;
if(current == null){
tail = newNode;
}
} else {
newNode.next = root;
root = newNode;
}
}
public static final void main(String[] args){
FileInputStream fileIn = null;
try{
fileIn = new FileInputStream("student_input.txt");
System.setIn(fileIn);
} catch(FileNotFoundException fnfe){
fnfe.printStackTrace(System.err);
}
//Do work here to create list of students
}
try{
fileIn.close();
} catch(Exception e){}
}
}
Student_input.txt:
1000
Lisa
Licata
2.28
1001
Shelley
Santoro
1.56
1002
Ok
Ota
3.33
1003
Cindi
Caggiano
1.65
Still not completely sure, maybe some variation of this.
Especially this inserts before the first Node that is bigger, and I am still not sure what the generics are for in this case and T needs to be something that extends Student(well it needs the compareTo method):
public void add(T data) {
for(Node<T> current = root; current != null; current = current.next) {
if (data.compareTo(current.data) <= 0) {
current = new Node<>(data,current.previous,current);
if(null == current.previous){
root = current;
}else {
current.previous.next = current;
}
if(null == current.next){
tail = current;
} else {
current.next.previous = current;
}
return;
}
}
tail = new Node<>(data,tail,null);
if(null == tail.previous) root=tail;
}
So your list should maybe look like this(to ensure T has the compareTo method):
public class DoublyLinkedList<T extends Student> implements Iterable<Node<T>> {
...
}
All together(To have Node as a seperate file like you do is better - but for brevity I put it into the list):
public class DoublyLinkedList<T extends Student> implements Iterable<Node<T>> {
public static class Node<S> {
Node<S> previous;
Node<S> next;
S data;
public Node(S data) {
this(data, null, null);
}
public Node(S data, Node<S> previous, Node<S> next) {
this.data = data;
this.previous = previous;
this.next = next;
}
}
private Node<T> root = null;
private Node<T> tail = null;
private class ListIterator implements Iterator<Node<T>> {
Node<T> current = root;
#Override
public boolean hasNext() {
return (current != null);
}
#Override
public Node<T> next() {
Node<T> answer;
answer = current;
current = current.next;
return answer;
}
}
#Override
public Iterator<Node<T>> iterator() {
ListIterator listIterator = new ListIterator();
return listIterator;
}
public void add(T data) {
for(Node<T> current = root; current != null; current = current.next) {
if (data.compareTo(current.data) <= 0) {
current = new Node<>(data,current.previous,current);
if(null == current.previous){
root = current;
}else {
current.previous.next = current;
}
if(null == current.next){
tail = current;
} else {
current.next.previous = current;
}
return;
}
}
tail = new Node<>(data,tail,null);
if(null == tail.previous) root=tail;
}
}

Sort Linkedlist with Comparator and Generics java

I'm trying to sort a linkedlist with generics but I'm having trouble with some casting issues. The code is throwing Bus can't be cast to Node. I know the problem is in the comparator (where I casted to Bus) but otherwise I don't know how could I call to the methods defined in Bus (irrelevant whether is Bus or another Object, just testing with a random one) . I've been researching the internet but couldn't find a solution. Here is the code:
/**
* Swaps the current node's element with the previous one
*/
public void swap(){
Object previous = getCurrent().getElement();
Object current = next().getElement();
getCurrent().setElement(previous);
previous().setElement(current);
}
public AbstractList<T> orderBy(Comparator<Node<T>> comparator){
setCurrent(getFirst());
Node<T> aux;
Node<T> current;
boolean check = true;
while (check){
check = false;
aux = getFirst();
current = getFirst().getNext();
while(hasNext()) {
if (comparator.compare(aux, current) > 0) {
check = true;
swap();
}
aux = current;
current = current.getNext();
}
}
return this;
}
The comparator:
import java.util.Comparator;
public class InternComparator implements Comparator<Node<Bus>>{
#Override
public int compare(Node<Bus> o1, Node<Bus> o2) {
return ((Bus)o1.getElement()).getIntern() - ((Bus)o2.getElement()).getIntern();
} //getIntern() returns an Integer
AbstractList (given by the professor):
import java.util.NoSuchElementException;
public class AbstractList<T> {
private Node<T> first;
private Node<T> current;
private Node<T> last;
private int size = 0;
public boolean hasNext(){
return current != last;
}
public boolean hasPrevious(){
return current != first;
}
public Node getCurrent(){
return current;
}
public void setCurrent(Node<T> current) {
this.current = current;
}
public int size(){
return size;
}
public boolean isEmpty(){
return first == last || first == null;
}
public void add(T t){
Node<T> a = new Node<T>(t);
if(first == null){
first = a;
}
if(last == null && first != null){
last = a;
last.setPrevious(first);
first.setNext(last);
}
Node<T> aux = last;
last.setNext(a);
last = a;
last.setPrevious(aux);
current = last;
size++;
}
public Node next(){
if(!hasNext()){
throw new RuntimeException("No elements available next.");
}
current = current.getNext();
return current;
}
public Node previous(){
if(!hasPrevious()){
throw new RuntimeException("No elements available previous.");
}
current = current.getPrevious();
return current;
}
public Node getFirst(){
return first;
}
public Node getLast(){
return last;
}
public void setFirst(Node<T> first){
this.first = first;
}
public void setLast(Node<T> last) {
this.last = last;
}
public void remove(T t){
current = first;
boolean removed = false;
while (hasNext()) {
if (current.getElement() == t || current.getElement().equals(t)) {
if(current != last && current != first) {
current.getNext().setPrevious(current.getPrevious());
current.getPrevious().setNext(current.getNext());
} else if(current == first){
current.getNext().setPrevious(null);
} else if(current == last){
current.getPrevious().setNext(null);
}
removed = true;
return;
}
current = next();
}
if(removed){
size--;
} else {
throw new NoSuchElementException("No such element on the list.");
}
}
public Node goTo(int pos){
if(pos > size){
throw new ArrayIndexOutOfBoundsException("Inexistent Position");
}
current = first;
for(int i = 0; i < pos; i++){
current = next();
}
return current;
}
public void insertAfter(T t){
Node<T> aux = new Node<>(t);
if(current != last) {
Node<T> next = current.getNext();
Node<T> previous = current;
current.getNext().setPrevious(aux);
current.setNext(aux);
aux.setNext(next);
aux.setPrevious(previous);
} else {
current.setNext(aux);
aux.setPrevious(current);
last = aux;
}
size++;
}
public void insertPrevious(T t){
Node<T> aux = new Node<>(t);
if(current != first) {
Node<T> previous = current.getPrevious();
Node<T> next = current;
current.getPrevious().setNext(aux);
current.setPrevious(aux);
aux.setNext(next);
aux.setPrevious(previous);
} else {
Node<T> aux1 = current;
current.setPrevious(aux);
first = aux;
first.setNext(aux1);
}
size++;
}
#Override
public String toString() {
String result = "";
current = first;
while(hasNext()) {
result += current.getElement() + "";
next();
}
return result;
}
}
class Node<T> {
private Object element;
private Node<T> prev;
private Node<T> next;
public Node(T element){
this.element = element;
}
public Node(T element, Node next){
this.element = element;
this.next = next;
}
public Node<T> getNext() {
return next;
}
public Node<T> getPrevious() {
return prev;
}
public Object getElement() {
return element;
}
public void setNext(Node<T> next) {
this.next = next;
}
public void setPrevious(Node<T> prev) {
this.prev = prev;
}
public void setElement(Object element) {
this.element = element;
}
}
Think again: your object is of type Node<Bus>; and you are wondering why the cast to Bus fails?
Or lets rephrase: do you assume that a Bus<People> represents a human being?
If you have a container, then you have to retrieve the contained value; and that can't be achieved by casting the container!
Or, to keep using strange pictures: you don't get an egg out of the box by declaring the box to be an egg. You open the box, and fetch the egg.

Linked List contains lines from a text file. Create find(int index) method which prints the content at the index positions passed as an argument

Please find the below code snippet for printing the content at index position passed as an argument. The list prepared contains the line read from a text file. It looks like
[ The abc......
....
]
Please correct it if anything wrong.
public class ContactList {
private ContactNode head;
private ContactNode last;
public ContactNode current;
public ContactList() {}
public void addNode(ContactNode input) {
if(this.head == null) {
this.head = input;
this.last = input;
} else
last.setNext(input);
input.setPrev(last);
this.last = input;
}
public void traverse() {
System.out.println();
current = this.head;
while (current != null) {
System.out.print( current.getName() + " ");
System.out.println("");
current = current.getNext();
}
System.out.println();
}
public void getFirst() {
current = this.head;
while (current != null) {
System.out.print("The first contact of the list is: "
+ current.getName());
break;
}
}
public void getLast(){
current = this.last;
while (current != null) {
System.out.print("The Last contact of the list is: "
+ current.getName());
break;
}
}
public ContactNode find(int index) {
ContactNode current = head;
while(current!=null) {
if(current.getIndex() == (index))
System.out.println(current.getName());
else
current = current.getNext();
System.out.println(current);
}
return null;
}
}
Thanks in advance
public class ContactNode{
private String name;
public int index;
private ContactNode prev;
public ContactNode next;
ContactNode(String a)
{ name = a;
index = 0;
next = null;
prev = null;}
ContactNode(){}
public ContactNode getNext()
{return next;}
public ContactNode getPrev()
{return prev;}
public String getName()
{return name;}
public int getIndex(){
return index;}
public void setNext(ContactNode newnext)
{next = newnext;}
public void setPrev(ContactNode newprevious)
{prev = newprevious;}
public void setName(String a)
{name=a;}
public void setIndex(int b)
{index=b;}
}
Main method class:
import java.util.Scanner;
import java.io.FileReader;
import java.io.FileNotFoundException;
public class ContactMain{
public static void main(String[]args){
try{
FileReader filepath = new FileReader("data1.txt");
Scanner k = new Scanner(filepath);
ContactList myList = new ContactList();
while (k.hasNextLine()){
String i = k.nextLine();
myList.addNode(new ContactNode(i));}
myList.traverse();
myList.getFirst();
myList.getLast();
myList.find(3);
}catch (FileNotFoundException e){
System.out.println("File Not Found. ");}}}
Instead of printing in your find method, actually return the node that you find.
Also it's unclear if your ContactNode class actually has a getIndex() method, so I'm going to assume it doesn't. In order to make up for this, we keep track of a count (with head = 0).
public ContactNode find(int index) {
ContactNode current = head;
while(current!=null) {
if(index == 0)
return current;
//we're not there yet. Move to next node, decrement index
current = current.getNext();
index--;
}
return null;
}

Use a linked list to implement a Priority Queue

I have implemented a priority queue using a linked list. In this priority queue the smallest int value has the highest value and therefore by calling the remove method the smallest method will be removed.
Code for Node Class
public class Node {
public int iData;
public Node next;
public Node(int x) {
iData = x;
}
public void displayNode() {
System.out.println(iData + " ");
}
}
Code for Link List
public class LinkList {
private Node first;
public LinkList() {
first = null;
}
public boolean isEmpty() {
return first == null;
}
public void insert(int x) {
Node newNode = new Node(x);
Node previous = null;
Node current = first;
while (current != null && x < current.iData) {
previous = current;
current = current.next;
}
if (previous == null) {
newNode.next = first;
first = newNode;
}
else {
previous.next = newNode;
newNode.next = current;
}
}
public Node remove() {
Node previous = null;
Node current = first;
Node temp = current;
while (current.next != null) {
previous = current;
current = current.next;
}
previous.next = null;
return temp;
}
public void display() {
Node current = first;
while (current != null) {
current.displayNode();
current = current.next;
}
System.out.println(" ");
}
}
Code for Priority Queue
public class PriorityQ {
private LinkList list;
public PriorityQ() {
list = new LinkList();
}
public void insert(int x) {
list.insert(x);
}
public void remove() {
list.remove();
}
public void displayList() {
System.out.println("Largest Value to Smallest");
list.display();
}
}
It is working fine at the moment, however i am not sure if my remove method in the link list class is the best way to go about removing elements. So i am looking for suggestions.
remove() is supposed to remove the first element from the list, right? Why do you loop anything for that?
Since your list is singly-linked (only pointing to next elements in the Node) all you need to do is:
Store the first in a temporary variable (if it's != null)
Then update first to be pointing to the 2nd item in the list
(first.next if != null)
Then return the temporary variable.
This can be implemented by having single pointer to first node and maintaining order by storing the smallest element to the first node.
public class LinkedListBasedOrderedMinPQ<T extends Comparable<T>> implements PriorityQueue<T> {
private Node<T> head;
private int size;
//Maintains an ordered linked list with the min element as the head
#Override
public void insert(T item) {
Node<T> node = head;
head = insert(node, item);
}
private Node<T> insert(Node<T> node, T item) {
Node<T> newNode = createNewNode(item);
if(null == node) {
return newNode;
}
if(node.data.compareTo(item) > 0) {
newNode.next = node;
node = newNode;
} else {
node.next = insert(node.next, item);
}
return node;
}
private Node<T> createNewNode(T item) {
size++;
return new Node<T>(item);
}
#Override
public T remove() {
if(null == head) {
return null;
}
T data = head.data;
head = head.next;
size--;
return data;
}
#Override
public int size() {
return size;
}
private static class Node<T> {
private final T data;
private Node<T> next;
public Node(T data) {
this.data = data;
}
#Override
public String toString() {
return "Node [data=" + data + ", next=" + next + "]";
}
}
}

Remove in Linked structure

Hello There I am trying to test removeCity(), but it didn't remove any element that I provide.
also the method addToList() if I use it in the City class I get "Exception in thread "main" java.lang.StackOverflowError" while it work fine in the test class
Any help ?
MyList
public class MyList<T> {
private Node head;
private Node tail;
public MyList(){
head = null;
tail = null;
}
public void addToTail(T info){
Node n;
//case 1: empty List
if(isEmpty()){
n = new Node(info, null);
head = n;
tail = head;
}
//case 2: if the list is not empty
else {
n = new Node(info, null);
tail.setNext(n);
tail = n;
}
}
public void addToHead(T info){
Node n;
//case 1: empty List
if(isEmpty()){
n = new Node(info, null);
head = n;
tail = head;
}
//case 2: if the list is not empty
else {
n = new Node(info, head);
head = n;
}
}
public boolean removeHead(){
//Case 1: if the list is empty
if(isEmpty())
return false;
//case 2: if the list have at least one element
else{
Node n = head.getNext();
head = n;
return true;
}
}
public boolean removeElement(String element){
//cacs 1 if before is the head
if(isEmpty())
return false;
if( ((City) head.getInfo()).getCode().equals(element)){
removeHead();
return true;
}
Node iter = head.getNext();
Node prev = head;
while(iter != null && !((City) head.getInfo()).getCode().equals(element)){
iter = iter.getNext();
prev = prev.getNext();
}
if(iter == null)
return false;
else{
prev.setNext(iter.getNext());
return true;
}
}
//To check if the list is empty
public boolean isEmpty(){
if ( head == null)
return true;
else
return false;
}
Node
public class Node<T> {
private T info;
private Node next;
public Node(){
info = null;
next = null;
}
public Node(T info, Node next){
this.info = info;
this.next = next;
}
public T getInfo(){
return info;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
public void setInfo(T info){
this.info = info;
}
}
City
public class City implements Serializable {
public static MyList<City> cityList = new MyList<City>();
private String name;
private String code;
public City(String name, String code) {
super();
this.name = name;
this.code = code;
addToList(new City(name,code));
}
public void addToList(City toAdd){
City.cityList.addToHead(toAdd);
}
public static void removeCity(String name){
if( cityList.isEmpty()){
System.out.println("The List is empty");
return;
}
if ( cityList.removeElement(name) == true )
System.out.println("The City was removed sucssesfully");
else
System.out.println("This city does not not exist");
}
}
Test
public class DummyTest {
public static void main(String [] args){
City x = new City("Ney York","NY");
City y = new City("London","LD");
System.out.println(City.cityList);
}
}
Stacktrace
Exception in thread "main" java.lang.StackOverflowError
at City.<init>(City.java:15)
at City.<init>(City.java:18)
at City.<init>(City.java:18)
Line 15 is the constructor
public City(String name, String code)
Line 18 is addToList
addToList(new City(name,code))
What I've spotted that you have an issue in your while loop in removeElement method.
I am not sure if it will solve your issue.
Could you also put a part of stacktrace here were do you get StackOverflowException.
Node iter = head.getNext();
Node prev = head;
while(iter != null && !((City) head.getInfo()).getCode().equals(element)){
iter = iter.getNext();
prev = prev.getNext();
}
this line
while(iter != null && !((City) head.getInfo()).getCode().equals(element))
should be probably
while(iter != null && !((City) iter.getInfo()).getCode().equals(element))
iter instead head
Alexey already found the first error, here are 2 more:
public City(String name, String code) {
super();
this.name = name;
this.code = code;
addToList(new City(name,code)); // <- infinite recursion
}
is infinite recursion: the (constructor-)method calls the (constructor-)method.
It should probably be addToList(this);
Also: In mylist.java all the new Node(..) should be new Node<T>(..).

Categories