Need help on unchecked operations java - java

I am learning algorithms myself, and I tried to implement LinkedList in Java with generic types from scratch. I had a version with Object which works well, but when I updated it with generic types, it gives warnings. Can anybody help where does the "unchecked or unsafe operations" come from?
class LinkedListGeneric <T> {
private Node<T> head;
private int size;
public LinkedListGeneric() {
head = null;
size = 0;
}
public int size() {
return size;
}
public void add (T data) {
if (head == null) {
head = new Node<T> (data);
size = 1;
}
else {
Node<T> temp = new Node<T> (data);
search(size).setNext(temp);
size++;
}
}
public void add (T data, int position) {
if (position > size + 1 || position <= 0) {
System.out.println ("error.");
return;
}
Node<T> temp = new Node<T> (data);
if (position == 1) {
temp.setNext(head);
head = temp;
return;
}
Node<T> prev = search(position - 1);
temp.setNext(prev.getNext());
prev.setNext(temp);
}
public void delete (int position) {
if (position > size || position <= 0) {
System.out.println ("error.");
return;
}
if (position == 1) {
size--;
head = head.getNext();
return;
}
Node<T> prev = search(position - 1);
prev.setNext(prev.getNext().getNext());
size--;
}
public T getValue (int position) {
if (position > size || position <= 0) {
System.out.println ("error.");
return null;
}
Node<T> temp = search(position);
return temp.getData();
//return search(position).getData();
}
public int searchData(T data) {
Node<T> temp = head;
int position = 1;
boolean flag = false;
while (temp != null) {
if (temp.getData() == data) {
flag = true;
break;
}
else {
temp = temp.getNext();
position++;
}
}
if (flag) return position;
else return -1;
}
public void print() {
Node<T> temp = head;
int position = 1;
while (temp != null) {
System.out.println("Node " + position + ": " + temp.getData());
temp = temp.getNext();
position++;
}
}
private Node<T> search (int position) {
Node temp = head;
while (position > 0) {
temp = temp.getNext();
}
return temp;
}
private class Node<T> {
private T data;
private Node<T> next;
public Node() {
this.data = null;
next = null;
}
public Node(T data) {
this.data = data;
next = null;
}
public T getData() {
return data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
}

The problem I see is your Node.getNext call is returning a Node instead of a Node<T>. This is equivalent to the method returning Node<Object> instead of the generic type.
So, you should change:
public Node getNext() {
return next;
}
to
public Node<T> getNext() {
return next;
}

Although sbochin's answer will fix some of your warnings, doing the following will fix all of them:
Replace all instances of T within your Node class, including the one in the class declaration, with T2.
Change the return of getNext to Node<T2>
Change the argument type in setNext to Node<T2>.
Change the type of temp in search to Node<T>.
You might also want to add an #SuppressWarnings("unused") to public Node() since that also generates a compiler warning.
You might also want to make your Node class a static class as none of it's methods depend on the LinkedListGeneric<T> object it is in.
Completely alternatively, you could just get rid of the type parameter from Node, which gets rid of all your warnings except the unused warning. You'd have to keep your class nonstatic however.

Related

How to implement toArray() within a linked list?

I've created a sorted linked list class, and the only part I'm struggling with is implementing the toArray() method properly.
public class SortedLinkedList<T extends Comparable<T>> implements ListInterface<T>
{
// container class
private class LinkedNode<T>
{
public T data;
public LinkedNode<T> next;
public LinkedNode(T data, LinkedNode<T> next)
{
this.data = data;
this.next = next;
}
}
// private variables
private LinkedNode<T> head, tail;
private int size;
private String name;
// constructor
public SortedLinkedList(String name)
{
head = null;
tail = null;
size = 0;
this.name = name;
}
// core functions
public void Add(T data)
{
size++;
// creation of new node to be added
LinkedNode<T> newNode = new LinkedNode<T>(data, null);
// check for empty list; adds node at head if so
if (head == null)
{
head = newNode;
return;
}
if (head.data.compareTo(data) < 0)
{
head = newNode;
return;
}
// insertion in middle
LinkedNode<T> current = head;
LinkedNode<T> prev = null;
while (current != null)
{
if (current.data.compareTo(data) > 0)
{
prev.next = newNode;
newNode.next = current;
return;
}
prev = current;
current = current.next;
}
// insertion at end
prev.next = newNode;
return;
}
public void Remove(T data)
{
if (head == null)
{
return;
}
LinkedNode<T> current = head.next;
while (current != null && current.next != null)
{
if (current.data.compareTo(current.next.data) == 0)
{
current.next = current.next.next;
} else {
current = current.next;
}
}
size--;
}
public int size()
{
return size;
}
#SuppressWarnings("unchecked")
public T[] toArray()
{
T[] result = (T[])(new Comparable[size()]);
int counter = 0;
for ( T item : )
{
result[counter++] = item;
}
return result;
}
The problem I'm having is what I should include after "T item : " in my for/each line. I had no problem with implementing a similar toArray() method in a set class recently, as that was "for each item in the set", but for some reason I'm blanking on what to place there for the linked list.
Try this.
#SuppressWarnings("unchecked")
public T[] toArray()
{
T[] result = (T[])(new Comparable[size()]);
int counter = 0;
for ( LinkedNode<T> cursor = head; cursor != null; cursor = cursor.next )
{
result[counter++] = cursor.data;
}
return result;
}
Actually, the answer to your question is this:
#SuppressWarnings("unchecked")
public T[] toArray() {
T[] result = (T[])(new Comparable[size()]);
int counter = 0;
for (T item : this) {
result[counter++] = item;
}
return result;
}
This is correct, but to do this you have to implement Iterable<T> interface:
public class SortedLinkedList<T extends Comparable<T>> implements ListInterface<T>, Iterable<T> {
#Override
public Iterator<T> iterator() {
return null;
}
// ...
}
Don't use for loop with linked-lists. Try something like below:
LinkedNode cursor = head;
int index = 0;
while (cursor != null ){
result[index] = cursor.data;
cursor = cursor.next;
index++;
}

How can this class be used and assigned in this manner?

I am currently trying to understand Singly linked lists.
I don't understand some of the code in the SinglyLinkedList.java class. How can the Node class be called and then assigned like: private Node first;
I would have thought that you would have to do something like this
Node<T> help =new Node<>();
help = first;
If someone could explain, or provide me to a link that would help me, it would be much appreciated.
Thanks!
public class Node<T> {
public T elem;
public Node<T> next;
public Node(T elem) {
this.elem = elem;
next = null;
}
public Node(T elem, Node<T> next) {
this.elem = elem;
this.next = next;
}
#Override
public String toString() {
return "Node{" + "elem=" + elem + '}';
}
}
package list;
/**
*
* #author dcarr
*/
public class SinglyLinkedList<T> implements List<T> {
private Node<T> first;
private Node<T> last;
public SinglyLinkedList() {
first = null;
last = null;
}
#Override
public boolean isEmpty() {
return first == null;
}
#Override
public int size() {
if (isEmpty()){
return 0;
} else {
int size = 1;
Node<T> current = first;
while(current.next != null){
current = current.next;
size++;
}
return size;
}
}
#Override
public T first() {
return first.elem;
}
#Override
public void insert(T elem) {
// if there is nothing in the list
if (isEmpty()){
first = new Node<>(elem);
last = first;
// if the list has elements already
} else {
// the new element will be the next of what was the last element
last.next = new Node<>(elem);
last = last.next;
}
}
#Override
public void remove(T elem) {
if (!isEmpty()){
int index = 0;
Node<T> current = first;
while (current != null && current.elem != elem){
current= current.next;
index++;
}
remove(index);
}
}
#Override
public String toString() {
if (isEmpty()){
return "Empty List";
} else {
String str = first.elem.toString() + " ";
Node<T> current = first;
while(current.next != null){
current = current.next;
str += current.elem.toString() + " ";
}
return str;
}
}
#Override
public void insertAt(int index, T e) {
if (index == 0){
first = new Node<>(e, first);
if (last == null){
last = first;
}
return;
}
Node<T> pred = first;
for (int i = 0; i < index-1; i++) {
pred = pred.next;
}
pred.next = new Node<>(e, pred.next);
System.out.println(pred);
if (pred.next.next == null){
// what does this mean pred.next is?
last = pred.next;
}
}
#Override
public void remove(int index) {
if (index < 0 || index >= size()){
throw new IndexOutOfBoundsException();
} else if (isEmpty()){
return;
}
if (index == 0){
first = first.next;
if (first == null){
last = null;
}
return;
}
Node<T> pred = first;
for (int i = 1; i <= index-1; i++) {
pred = pred.next;
}
// remove pred.next
pred.next = pred.next.next;
if (pred.next == null){
last = pred;
}
}
}
The first field is automatically initialized to null:
private Node<T> first;
I assume there will be some method to add an element at the end like so:
public void add(T element) {
if (first == null) {
first = new Node<T>(element);
last = first;
}
else {
last.next = new Node<>(element);
last = last.next;
}
}
So when you create a new SinglyLinkedList:
SinglyLinkedList<String> sillyList = new SinglyLinkedList<>();
The first and last fields both hold a null reference.
Note that the first method will cause a NullPointerException at this point. A better implementation would be:
#Override
public Optional<T> first() {
if (first != null) {
return Optional.ofNullable(first.elem);
}
else {
return Optional.empty();
}
}
Now if you add an element:
sillyList.add("Adam");
The code executed in the add method is:
first = new Node<>(elem);
last = first;
So first points to a new Node instance with an elem field holding the value "Adam". And last points to that same Node instance.
Some of the methods in this class I would implement differently, for example:
#Override
public void remove(int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index cannot be negative");
}
else if (index == 0 && first != null) {
first = null;
last = null;
}
else {
Node<T> curr = new Node<>("dummy", first);
int c = 0;
while (curr.next != null) {
if (c == index) {
curr.next = curr.next.next;
if (curr.next == null) {
last = curr;
}
return;
}
curr = curr.next;
c++;
}
throw new IndexOutOfBoundsException(String.valueOf(c));
}
Also, some of the methods don't actually exist in the java.util.List interface, like insert, insertAt and first. So these methods must not have the #Override annotation.

Writing a size() method for a user-defined Stack class (Linked List)

I'm making my own generic stack data structure using a linked list as the backbone to it but I am in need of making a size() method similar to the built in size method for stacks. I'm unsure of the proper way of doing it with a Linked List structure?
public class LLStack<T> implements StackInterface {
private class ListNode
{
private T data;
private ListNode link;
public ListNode(T aData, ListNode aLink)
{
data = aData;
link = aLink;
}
}
private ListNode head;
public LLStack()
{
head = null;
}
public void push(Object data)
{
ListNode newNode = new ListNode((T)data, head);
head = newNode;
}
public T pop()
{
if(head == null)//Empty stack
return null;
T retVal = head.data;
head = head.link;
return retVal;
}
public T peek()
{
if(head == null)
return null;
else
return head.data;
}
public void print()
{
ListNode temp = head;
while(temp != null)
{
System.out.println(temp.data);
temp = temp.link;
}
}
public int size() {
}
It's basically the exact same as the print method.
public int size()
{
ListNode temp = head;
int size = 0;
while(temp != null)
{
size += 1;
temp = temp.link;
}
return size;
}
It's more optimal to store a size field that updates with each pop and push, though. I'll leave that as an exercise for you.
Like this:
Keep a size variable in the class:
public class LLStack<T> implements StackInterface {
{
private int size;
....
In your push and pop methods, increment / decrement the size:
public void push(Object data)
{
ListNode newNode = new ListNode((T)data, head);
head = newNode;
size ++;
}
public T pop()
{
if(head == null)//Empty stack
return null;
size --;
T retVal = head.data;
head = head.link;
return retVal;
}
Then have a get size method:
public int getSize()
{
return size;
}
There are two simple ways of doing what you want:
Count the list by doing an end-to-end traversal every time the method is called. This is going to be slow and I would not recommend it outside an illustrative example. This way you do not need to store the size as a field:
public int size() {
ListNode current = head;
int count;
for(count = 0; current != null; count++)
current = current.link;
return count;
}
A much better way would be to just maintain the count as a private field. The size method would just be a fast getter:
public int size() { return this.count; }
You would have to modify all the methods that change the size to change the value of this field as well:
public LLStack() {
this.head = null;
this.count = 0;
}
public void push(T data) {
...
this.count++;
}
public T pop() {
...
this.count--;
return retval;
}

Java: Converting a single-linked list into a doubly linked list from scratch

This is for a class assignment; I currently have a single-linked list and need to convert it into a doubly-linked list. Currently, the list is a collection of historical battles.
What in this program needs to be changed to turn this into a double-linked list? I feel like I'm really close, but stuck on a certain part (What needs to be changed in the 'add' part)
public static MyHistoryList HistoryList;
public static void main(String[] args) {
//Proof of concept
HistoryList = new MyHistoryList();
HistoryList.add("Battle of Vienna");
HistoryList.add("Spanish Armada");
HistoryList.add("Poltava");
HistoryList.add("Hastings");
HistoryList.add("Waterloo");
System.out.println("List to begin with: " + HistoryList);
HistoryList.insert("Siege of Constantinople", 0);
HistoryList.insert("Manzikert", 1);
System.out.println("List following the insertion of new elements: " + HistoryList);
HistoryList.remove(1);
HistoryList.remove(2);
HistoryList.remove(3);
System.out.println("List after deleting three things " + HistoryList);
}
}
class MyHistoryList {
//setting up a few variables that will be needed
private static int counter;
private Node head;
This is the private class for the node, including some getters and setters. I've already set up 'previous', which is supposed to be used in the implementation of the doubly-linked list according to what I've already googled, but I'm not sure how to move forward with the way MY single-list is set up.
private class Node {
Node next;
Node previous;
Object data;
public Node(Object dataValue) {
next = null;
previous = null;
data = dataValue;
}
public Node(Object dataValue, Node nextValue, Node previousValue) {
previous = previousValue;
next = nextValue;
data = dataValue;
}
public Object getData() {
return data;
}
public void setData(Object dataValue) {
data = dataValue;
}
public Node getprevious() {
return previous;
}
public void setprevious(Node previousValue) {
previous = previousValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
This adds elements to the list. I think I need to change this part in order to make this into a doubly-linked list, but don't quite understand how?
public MyHistoryList() {
}
// puts element at end of list
public void add(Object data) {
// just getting the node ready
if (head == null) {
head = new Node(data);
}
Node Temp = new Node(data);
Node Current = head;
if (Current != null) {
while (Current.getNext() != null) {
Current = Current.getNext();
}
Current.setNext(Temp);
}
// keeping track of number of elements
incrementCounter();
}
private static int getCounter() {
return counter;
}
private static void incrementCounter() {
counter++;
}
private void decrementCounter() {
counter--;
}
This is just tostring, insertion, deletion, and a few other things. I don't believe anything here needs to be changed to make it a doubly linked list?
public void insert(Object data, int index) {
Node Temp = new Node(data);
Node Current = head;
if (Current != null) {
for (int i = 0; i < index && Current.getNext() != null; i++) {
Current = Current.getNext();
}
}
Temp.setNext(Current.getNext());
Current.setNext(Temp);
incrementCounter();
}
//sees the number of elements
public Object get(int index)
{
if (index < 0)
return null;
Node Current = null;
if (head != null) {
Current = head.getNext();
for (int i = 0; i < index; i++) {
if (Current.getNext() == null)
return null;
Current = Current.getNext();
}
return Current.getData();
}
return Current;
}
// removal
public boolean remove(int index) {
if (index < 1 || index > size())
return false;
Node Current = head;
if (head != null) {
for (int i = 0; i < index; i++) {
if (Current.getNext() == null)
return false;
Current = Current.getNext();
}
Current.setNext(Current.getNext().getNext());
decrementCounter();
return true;
}
return false;
}
public int size() {
return getCounter();
}
public String toString() {
String output = "";
if (head != null) {
Node Current = head.getNext();
while (Current != null) {
output += "[" + Current.getData().toString() + "]";
Current = Current.getNext();
}
}
return output;
}
}

How to find the max/min element of linked list

I have a doubly linked list in my case. And I want to find the max and min element. So I want to use the Collections to find it. Here is my code below for Node first:
public class Node<T> {
Node<T> prev;
Node<T> next;
T data;
public Node(T _data)
{
data = _data;
prev = null;
next = null;
}
public Node(T _data, Node<T> _prev, Node<T> _next)
{
data = _data;
prev = _prev;
next = _next;
}
T getData()
{
return data;
}
public void setNext(Node<T> _next)
{
next = _next;
}
public void setPrev(Node<T> _prev)
{
prev = _prev;
}
public Node<T> getNext()
{
return next;
}
public Node<T> getPrev()
{
return prev;
}
}
And here is my Doubly Linked List class:
public class DoublyLinkedList<T> {
private Node<T> head;
private Node<T> tail;
int listCount = 0;
public void traverseF()
{
Node<T> temp = head;
while(temp != null)
{
System.out.print(temp.getData() + " ");
temp = temp.getNext();
}
}
public void traverseB()
{
Node<T> temp = tail;
while(temp != null)
{
System.out.print(temp.getData() + " ");
temp = temp.getPrev();
}
}
public void insertFirst(T data)
{
Node<T> temp = new Node<T>(data);
if(head == null)
{
head = temp;
tail = temp;
temp.setNext(null);
temp.setPrev(null);
}
else
{
temp.setNext(head);
head.setPrev(temp);
head = temp;
}
}
}
So, my main code is:
import java.util.Collections;
public class glavna {
public static void main(String[] args) {
DoublyLinkedList<Integer> DLL = new DoublyLinkedList<Integer>();
DLL.insertFirst(32);
DLL.insertFirst(22);
DLL.insertFirst(55);
DLL.insertFirst(10);
DLL.traverseF();
Integer max = Collections.max(DLL);
}
}
How exactly do I call the Collections.max or Collections.min method? Isn't the list only necessary to find the max/min elements?
public T getMin()
{
Node<T> temp = head;
T min = head.getData();
while(temp.getNext() != null)
{
if(temp.getData() < min) // error
{
//min = temp.getData();
}
}
}
To implement getMin with generics you need to be able to compare them. You can, for instance, provide a custom Comparator to your method:
public T getMin(Comparator<? super T> comparator) {
Node<T> temp = head.getNext();
T min = head.getData();
while(temp != null) {
T candidateValue = temp.getData();
if (comparator.compare(candidateValue, min) < 0) { // equivalent to candidate < min
min = candidateValue;
}
temp = temp.getNext();
}
return min;
}
Then, calling your method for Integer :
getMin(new Comparator<Integer>() {
#Override
public int compare(Integer arg0, Integer arg1) {
return arg0.compareTo(arg1);
}
});
Another approach is to make your list only keep Comparable items :
public class DoublyLinkedList<T extends Comparable<? super T>> {
and then have your getMin() method use compareTo method :
public T getMin() {
Node<T> temp = head.getNext();
T min = head.getData();
while(temp != null) {
T candidateValue = temp.getData();
if (candidateValue.compareTo(min) < 0) { // equivalent to candidate < min
min = candidateValue;
}
temp = temp.getNext();
}
return min;
}
Second approach is less verbose, as Integer is Comparable (i.e. implements Comparable for you already), so you won't need to change any other code.
You list is not a Collection, so you cannot use Collections with it.
The Collections.max method expects an argument which implements Collection. The easiest way would probably be to extend AbstractCollection and add these methods:
#Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private Node<T> node = head;
#Override
public boolean hasNext() {
return node != null;
}
#Override
public T next() {
T next = node.data;
node = node.getNext();
return next;
}
};
}
#Override
public int size() {
int size = 0;
Node<T> node = head;
while (node != null) {
size++;
node = node.getNext();
}
return size;
}

Categories

Resources