Extract common objects from an arraylist - arraylist

I have a list like shown below. Assume it has 16 Container objects in it. Each Container object is a simple bean, with fields like age, weight, height, etc. How can I create a sub-list that contains common 'Container' objects if a 'Container' object is considered equal if the weight and height are equal?
List<Container> containers = new ArrayList<Container>();

If by "common" containers you mean duplicating ones, then this code might help you:
import java.util.ArrayList;
import java.util.List;
public class CommonContainers {
public static void main(String[] args) {
List<Container> containers = new ArrayList<Container>(16);
for(int i=0; i<13; i++) {
containers.add(new Container(i, i));
}
//add a few duplicating ones
containers.add(new Container(1,1));
containers.add(new Container(5,5));
containers.add(new Container(6,6));
List<Container> sublist = new ArrayList<Container>();
for (Container c1 : containers) {
for (Container c2 : containers) {
if(c1 != c2 && c1.equals(c2)) {
sublist.add(c1);
}
}
}
for (Container c : sublist) {
System.out.println(c);
}
}
private static class Container {
private int weight;
private int height;
#Override
public String toString() {
return String.format("Container[w=%d,h=%d]", weight, height);
}
public Container(int weight, int height) {
this.weight = weight;
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + height;
result = prime * result + weight;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Container other = (Container) obj;
if (height != other.height)
return false;
if (weight != other.weight)
return false;
return true;
}
}
}
If you mean something else or need clarification, please let me know.

Thanks John Smith for giving direction on this question. I used the iterator instead and was able to make a nice solution to what I was looking for. below is the solution. Note that .equals is overriden for the Containers comparison. The technique I used will take the master list and create a sub-list while removing elements from the parent list at the same time. The solution can be called recursivly until you convert the master list into a subset of lists.
public List<Container> extractCommonSubList(
List<Container> masterContainerList) {
List<Container> subList = new ArrayList<Container>();
ListIterator<Container> iterator = masterContainerList.listIterator();
// get first item from master list and remove from master list
Container firstContainer = iterator.next();
iterator.remove();
// Add first container to sublist
subList.add(firstContainer);
while (iterator.hasNext()) {
Container container = iterator.next();
// Search for matches
if (firstContainer.equals(container)) {
// containers are a match, continue searching for matches
subList.add(container);
iterator.remove();
continue;
} else {
break;
}
}
// return common list
return subList;
}

Related

How to find if items in 2 list match (but can't use direct equality)

I have this code here, to see if the items in both lists are identical:
for (final car in this.cars) {
bool found = false;
for (final car2 in garage2.cars) {
if (car2.id == car.id) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
(I previously check if the 2 list lengths are equal). Is there a way to rewrite that so that I don't have O(n2) complexity?
As an option you can override quals and hashcode methods for class Car
something like this
class Car {
int id;
// other fields
#override
bool operator ==(Object o) => o is Car && id == o.id;
#override
int get hashCode => id.hashCode;
}
and then you can use the native method listEquals, which compares for deep equality.
import 'package:flutter/foundation.dart';
bool isEqual = listEquals<Car>(cars, garage2.cars);

Generic BST having trouble getting constructor to work

I have been given some code from my instructor and i need to implement several functions. I have added the insert method but I can not figure out how or what the constructor is looking for, I don't understand why this call to construct a tree is not working. Not very strong in java but understand the logic of a BST
public class BinaryTreeDriver {
public static void main(String[] args){
BinaryTree<Integer> numbers = new BinaryTree<>();
I am getting compiler error cannot infer type arguments BinaryTree<>
Copying rest of code below
public class BinaryTree<T extends Comparable<T>> {
private BinaryTreeNode<T> root; // the root of the tree
private BinaryTreeNode<T> cursor; // the current node
/**
* Constructor for initializing a tree with node
* being set as the root of the tree.
* #param node
*/
public BinaryTree(BinaryTreeNode<T> node) {
root = node;
}
/**
* Moves the cursor to the root.
*/
public void toRoot() {
cursor = root;
}
/**
* Returns the cursor node.
* #return cursor
*/
public BinaryTreeNode<T> getCursor() {
return cursor;
}
/**
* Sets the root to the provided node.
* ONLY USE IN THE DELETE METHOD
* #param node
*/
public void setRoot(BinaryTreeNode<T> node) {
root = node;
}
/**
* Checks if the tree node has a left child node
* #return true if left child exists else false
*/
public boolean hasLeftChild() {
return cursor.getLeft() != null;
}
/**
* Checks if the tree node has a right child node
* #return true if right child exists else false
*/
public boolean hasRightChild() {
return cursor.getRight() != null;
}
/**
* Move the cursor to the left child
*/
public void toLeftChild() {
cursor = cursor.getLeft();
}
/**
* Move the cursor to the right child
*/
public void toRightChild() {
cursor = cursor.getRight();
}
/**
* #return height of the tree
*/
public int height() {
if (root != null) {
return root.height();
} else {
return 0;
}
}
**/**
* Tree-Insert
*/
public boolean insert(T elem)
{
return insert(root, elem);
}
public boolean insert(BinaryTreeNode start, T elem)
{
if (start == null)
{
root = new BinaryTreeNode<T>(elem, null, null);
return true;
}
int comparison = start.getData().compareTo(elem);
if (comparison > 0)
{
if (start.getLeft() == null)
{
start.setLeft(new BinaryTreeNode(elem, null, null));
return true;
}
return insert(start.getLeft(), elem);
}
else if (comparison < 0)
{
if (start.getRight() == null)
{
start.setRight(new BinaryTreeNode(elem, null, null));
return true;
}
return insert(start.getRight(), elem);
}
else
{
return false;
}**
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
public String toString() {
if (root != null) {
return root.toStringPreOrder(".");
} else {
return "";
}
}
}
public class BinaryTreeNode<T extends Comparable<T>> {
private BinaryTreeNode<T> left; // the left child
private BinaryTreeNode<T> right; // the right child
private T data; // the data in this node
public BinaryTreeNode() {
this(null, null, null);
}
public BinaryTreeNode(T theData) {
this(theData, null, null);
}
public BinaryTreeNode(T theData, BinaryTreeNode<T> leftChild,
BinaryTreeNode<T> rightChild) {
data = theData;
left = leftChild;
right = rightChild;
}
public T getData() {
return data;
}
public BinaryTreeNode<T> getLeft() {
return left;
}
public BinaryTreeNode<T> getRight() {
return right;
}
public void setLeft(BinaryTreeNode<T> newLeft) {
left = newLeft;
}
public void setRight(BinaryTreeNode<T> newRight) {
right = newRight;
}
public void setData(T newData) {
data = newData;
}
public void preOrder() {
System.out.println(data);
if (left != null) {
left.preOrder();
}
if (right != null) {
right.preOrder();
}
}
public int height() {
int leftHeight = 0; // Height of the left subtree
int rightHeight = 0; // Height of the right subtree
int height = 0; // The height of this subtree
// If we have a left subtree, determine its height
if (left != null) {
leftHeight = left.height();
}
// If we have a right subtree, determine its height
if (right != null) {
rightHeight = right.height();
}
// The height of the tree rooted at this node is one more than the
// height of the 'taller' of its children.
if (leftHeight > rightHeight) {
height = 1 + leftHeight;
} else {
height = 1 + rightHeight;
}
// Return the answer
return height;
}
/**
* #param pathString
* #return the tree nodes in pre-order traversal
*/
public String toStringPreOrder(String pathString) {
String treeString = pathString + " : " + data + "\n";
if (left != null) {
treeString += left.toStringPreOrder(pathString + "L");
}
if (right != null) {
treeString += right.toStringPreOrder(pathString + "R");
}
return treeString;
}
}

OptaPlaner simple example cant find feasible solution

to get familiar with optaplanner i created a simple test project. I only have one Solution and one Entity class. The Entity has only one value between 0 and 9. There should only be odd numbers and the sum of all should be less then 10 (this are just some random constraints i came up with).
As Score i use a simple HardSoftScore. Here is the code:
public class TestScoreCalculator implements EasyScoreCalculator<TestSolution>{
#Override
public HardSoftScore calculateScore(TestSolution sol) {
int hardScore = 0;
int softScore = 0;
int valueSum = 0;
for (TestEntity entity : sol.getTestEntities()) {
valueSum += entity.getValue() == null? 0 : entity.getValue();
}
// hard Score
for (TestEntity entity : sol.getTestEntities()) {
if(entity.getValue() == null || entity.getValue() % 2 == 0)
hardScore -= 1; // constraint: only odd numbers
}
if(valueSum > 10)
hardScore -= 2; // constraint: sum should be less than 11
// soft Score
softScore = valueSum; // maximize
return HardSoftScore.valueOf(hardScore, softScore);
}
}
and this is my config file:
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!-- Domain model configuration -->
<scanAnnotatedClasses/>
<!-- Score configuration -->
<scoreDirectorFactory>
<easyScoreCalculatorClass>score.TestScoreCalculator</easyScoreCalculatorClass>
</scoreDirectorFactory>
<!-- Optimization algorithms configuration -->
<termination>
<secondsSpentLimit>30</secondsSpentLimit>
</termination>
</solver>
for some reason OptaPlanner cant find a feasible solution. It terminates with LS step (161217), time spent (29910), score (-2hard/10soft), best score (-2hard/10soft)... and the solution 9 1 0 0.
So the hardScore is -2 because the two 0 are not odd. A possible solution would be 7 1 1 1 for example. Why is this ? This should be a really easy example ...
(when i set the Start values to 7 1 1 1 it terminates with this solution and a score of (0hard/10soft) how it should be)
Edit:
The Entity class
#PlanningEntity
public class TestEntity {
private Integer value;
#PlanningVariable(valueRangeProviderRefs = {"TestEntityValueRange"})
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
#ValueRangeProvider(id = "TestEntityValueRange")
public CountableValueRange<Integer> getStartPeriodRange() {
return ValueRangeFactory.createIntValueRange(0, 10);
}
}
The Solution class
#PlanningSolution
public class TestSolution {
private List<TestEntity> TestEntities;
private HardSoftScore score;
#PlanningEntityCollectionProperty
public List<TestEntity> getTestEntities() {
return TestEntities;
}
public void setTestEntities(List<TestEntity> testEntities) {
TestEntities = testEntities;
}
#PlanningScore
public HardSoftScore getScore() {
return score;
}
public void setScore(HardSoftScore score) {
this.score = score;
}
#Override
public String toString() {
String str = "";
for (TestEntity testEntity : TestEntities)
str += testEntity.getValue()+" ";
return str;
}
}
The Main Program class
public class Main {
public static final String SOLVER_CONFIG = "score/TestConfig.xml";
public static int printCount = 0;
public static void main(String[] args) {
init();
}
private static void init() {
SolverFactory<TestSolution> solverFactory = SolverFactory.createFromXmlResource(SOLVER_CONFIG);
Solver<TestSolution> solver = solverFactory.buildSolver();
TestSolution model = new TestSolution();
List<TestEntity> list = new ArrayList<TestEntity>();
// list.add(new TestEntity(){{setValue(7);}});
// list.add(new TestEntity(){{setValue(1);}});
// list.add(new TestEntity(){{setValue(1);}});
// list.add(new TestEntity(){{setValue(1);}});
for (int i = 0; i < 4; i++) {
list.add(new TestEntity());
}
model.setTestEntities(list);
// Solve the problem
TestSolution solution = solver.solve(model);
// Display the result
System.out.println(solution);
}
}
It gets stuck in a local optima because there is no move that takes 1 from entity and gives it to another entity. With a custom move you can add that.
These kind of moves only apply to numeric value ranges (which are rare, usually value ranges are a list of employees etc), but they should probably exist out of the box (feel free to create a jira for them).
Anyway, another way to get the good solution is to add <exhaustiveSearch/>, that bypassing local search and therefore the local optima. But that doesn't scale well.

How to deserialize a JSON array to a singly linked list by using Jackson

I want to deserialize a JSON array to a singly linked list in Java.
The definition of singly linked list is as the following:
public class SinglyLinkedListNode<T> {
public T value;
public SinglyLinkedListNode next;
public SinglyLinkedListNode(final T value) {
this.value = value;
}
}
How to deserialize a JSON string such as [1,2,3,4,5] in to a singly linked list?
public void typeReferenceTest() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
final ArrayList<Integer> intArray = objectMapper.readValue("[1,2,3,4,5]",
new TypeReference<ArrayList<Integer>>() {});
System.out.println(intArray);
// How to achieve this?
final ArrayList<Integer> intList = objectMapper.readValue("[1,2,3,4,5]",
new TypeReference<SinglyLinkedListNode<Integer>>() {});
System.out.println(intList);
}
Moreover, I want the SinglyLinkedListNode to be a first-class citizen the same as ArrayList, which can be used in all kinds of combinations, such as HashSet<SinglyLinkedListNode<Integer>>, SinglyLinkedListNode<HashMap<String, Integer>>.
For example, what happens if I want to deserialize [[1,2,3], [4,5,6]] into a ArrayList<SinglyLinkedListNode<Integer>> ?
As far as I know, a customized deserializer extending JsonDeserializer is not enough to do this.
When you want it to be deserialized to ArrayList<SinglyLinkedListNode<Integer>> for example. Your code specifies that is the type that expected. Therefore it should if a deserializer for SinglyLinkedListNode<Integer> is regeistered it will succeed.
From the jackson-user google group I get the right answer from #Tatu Saloranta.
The answer is simple: just implement the java.util.List interface, and Jackson will automatically serialize/deserialize between JSON array and SinglyLinkedListNode.
So I implement the java.util.List interface for SinglyLinkedListNode, the code is as the following:
import java.util.*;
import java.util.function.Consumer;
/**
* Singly Linked List.
*
* <p>As to singly linked list, a node can be viewed as a single node,
* and it can be viewed as a list too.</p>
*
* #param <E> the type of elements held in this collection
* #see java.util.LinkedList
*/
public class SinglyLinkedListNode<E>
extends AbstractSequentialList<E>
implements Cloneable, java.io.Serializable {
public E value;
public SinglyLinkedListNode<E> next;
/**
* Constructs an empty list.
*/
public SinglyLinkedListNode() {
value = null;
next = null;
}
/**
* Constructs an list with one elment.
*/
public SinglyLinkedListNode(final E value) {
this.value = value;
next = null;
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* #param c the collection whose elements are to be placed into this list
* #throws NullPointerException if the specified collection is null
*/
public SinglyLinkedListNode(Collection<? extends E> c) {
this();
addAll(c);
}
/**
* Links e as last element.
*/
void linkLast(E e) {
final SinglyLinkedListNode<E> l = last();
final SinglyLinkedListNode<E> newNode = new SinglyLinkedListNode<>(e);
if (l == null)
this.value = e;
else
l.next = newNode;
modCount++;
}
/**
* Inserts element e before non-null Node succ.
*/
void linkBefore(E e, SinglyLinkedListNode<E> succ) {
assert succ != null;
final SinglyLinkedListNode<E> prev = this.previous(succ);
final SinglyLinkedListNode<E> newNode = new SinglyLinkedListNode<>(e);
if (prev == null)
this.value = e;
else
prev.next = newNode;
modCount++;
}
/**
* Return the node before x.
*
* #param x current node
* #return the node before x
*/
private SinglyLinkedListNode<E> previous(final SinglyLinkedListNode<E> x) {
assert (x != null);
if (size() < 2) return null;
if (this == x) return null;
SinglyLinkedListNode<E> prev = new SinglyLinkedListNode<>();
prev.next = this;
SinglyLinkedListNode<E> cur = this;
while (cur != x) {
prev = prev.next;
cur = cur.next;
}
return prev;
}
/**
* Return the last node.
* #return the last node.
*/
private SinglyLinkedListNode<E> last() {
if (size() == 0) return null;
if (size() == 1) return this;
SinglyLinkedListNode<E> prev = new SinglyLinkedListNode<>();
prev.next = this;
SinglyLinkedListNode<E> cur = this;
while (cur != null) {
prev = prev.next;
cur = cur.next;
}
return prev;
}
/**
* Unlinks non-null node x.
*/
E unlink(SinglyLinkedListNode<E> x) {
assert x != null;
final E element = x.value;
final SinglyLinkedListNode<E> next = x.next;
final SinglyLinkedListNode<E> prev = previous(x);
if (prev == null) {
this.value = next.value;
this.next = next.next;
} else {
prev.next = next;
}
x.next = null;
modCount++;
return element;
}
/**
* #inheritDoc
*/
public ListIterator<E> listIterator(int index) {
checkPositionIndex(index);
return new ListItr(index);
}
private class ListItr implements ListIterator<E> {
private SinglyLinkedListNode<E> lastReturned;
private SinglyLinkedListNode<E> next;
private int nextIndex;
private int expectedModCount = modCount;
ListItr(int index) {
assert isPositionIndex(index);
next = (index == size()) ? null : node(index);
nextIndex = index;
}
public boolean hasNext() {
return nextIndex < size();
}
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.value;
}
public boolean hasPrevious() {
return nextIndex > 0;
}
public E previous() {
throw new UnsupportedOperationException();
}
public int nextIndex() {
return nextIndex;
}
public int previousIndex() {
return nextIndex - 1;
}
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
unlink(lastReturned);
nextIndex--;
lastReturned = null;
expectedModCount++;
}
public void set(E e) {
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.value = e;
}
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (modCount == expectedModCount && nextIndex < size()) {
action.accept(next.value);
lastReturned = next;
next = next.next;
nextIndex++;
}
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
/**
* #inheritDoc
*/
public int size() {
int size = 0;
if (value == null) return size;
SinglyLinkedListNode<E> cur = this;
while (cur != null) {
size++;
cur = cur.next;
}
return size;
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* Returns the (non-null) Node at the specified element index.
*/
SinglyLinkedListNode<E> node(int index) {
assert isElementIndex(index);
SinglyLinkedListNode<E> x = this;
for (int i = 0; i < index; i++)
x = x.next;
return x;
}
/**
* Tells if the argument is the index of an existing element.
*/
private boolean isElementIndex(int index) {
return index >= 0 && index < size();
}
/**
* Tells if the argument is the index of a valid position for an
* iterator or an add operation.
*/
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size();
}
/**
* Constructs an IndexOutOfBoundsException detail message.
* Of the many possible refactorings of the error handling code,
* this "outlining" performs best with both server and client VMs.
*/
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: " + size();
}
}
Here is the unit test code:
#Test public void typeReferenceTest() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
final SinglyLinkedListNode<Integer> intList = objectMapper.readValue("[1,2,3,4,5]",
new TypeReference<SinglyLinkedListNode<Integer>>() {});
System.out.println(intList);
final ArrayList<SinglyLinkedListNode<Integer>> arrayOfList = objectMapper.readValue("[[1,2,3], [4,5,6]]",
new TypeReference<ArrayList<SinglyLinkedListNode<Integer>>>() {});
System.out.println(arrayOfList);
}
#Tatu Saloranta Thank you very much!
Here is my original blog, Deserialize a JSON Array to a Singly Linked List

addFirst(E e) Doubly Linked List (Null Pointer Exception)

import java.util.*;
public class MyTwoWayLinkedList<E> extends java.util.AbstractSequentialList<E> {
private Node<E> head, tail;
private int size = 0;
private List<E> list;
/** Create a default list */
public MyTwoWayLinkedList() {
list = new LinkedList<E>();
}
public MyTwoWayLinkedList(E[] objects) {
list = new LinkedList<E>();
for (int i = 0; i < objects.length; i++)
add(objects[i]);
}
/** Return the head element in the list */
public E getFirst() {
if (size == 0) {
return null;
}
else {
return head.element;
}
}
/** Return the last element in the list */
public E getLast() {
if (size == 0) {
return null;
}
else {
return tail.element;
}
}
/** Add an element to the beginning of the list */
public void addFirst(E e) {
Node<E> newNode = new Node<E>(e); // Create a new node
newNode.next = head; // link the new node with the head
head.previous = newNode; //link the old node with new head
head = newNode; // head points to the new node
size++; // Increase list size
if (tail == null) // the new node is the only node in list
tail = head;
}
/** Add an element to the end of the list */
public void addLast(E e) {
Node<E> newNode = new Node<E>(e); // Create a new for element e
if (tail == null) {
head = tail = newNode; // The new node is the only node in list
}
else {
tail.next = newNode;// Link the new with the last node
newNode.previous = tail;
tail = tail.next; // tail now points to the last node
}
size++; // Increase size
}
#Override /** Add a new element at the specified index
* in this list. The index of the head element is 0 */
public void add(int index, E e) {
if (index == 0) {
addFirst(e);
}
else if (index >= size) {
addLast(e);
}
else {
Node<E> current = tail;
for (int i = size - 1; i > index; i--) {
current = current.previous;
}
Node<E> temp = current.next;
current.next = new Node<E>(e);
(current.next).previous = current;
(current.next).next = temp;
size++;
}
}
/** Remove the head node and
* return the object that is contained in the removed node. */
public E removeFirst() {
if (size == 0) {
return null;
}
else {
Node<E> temp = head;
head = head.next;
head.previous = null;
size--;
if (head == null) {
tail = null;
}
return temp.element;
}
}
/** Remove the last node and
* return the object that is contained in the removed node. */
public E removeLast() {
if (size == 0) {
return null;
}
else if (size == 1) {
Node<E> temp = head;
head = tail = null;
size = 0;
return temp.element;
}
else {
Node<E> temp = tail;
tail = tail.previous;
tail.next = null;
size--;
return temp.element;
}
}
#Override /** Remove the element at the specified position in this
* list. Return the element that was removed from the list. */
public E remove(int index) {
if (index < 0 || index >= size) {
return null;
}
else if (index == 0) {
return removeFirst();
}
else if (index == size - 1) {
return removeLast();
}
else {
Node<E> previous = tail;
for (int i = size - 1; i > index; i--) {
previous = previous.previous;
}
Node<E> current = previous.next;
(current.next).previous = previous;
previous.next = current.next;
size--;
return current.element;
}
}
#Override /** Override toString() to return elements in the list */
public String toString() {
StringBuilder result = new StringBuilder("[");
Node<E> current = tail;
for (int i = size - 1; i > 0; i--) {
result.append(current.element);
current = current.previous;
if (current != null) {
result.append(" ,"); // Separate two elements with a comma
}
else {
result.append("["); // Insert the closing ] in the string
}
}
return result.toString();
}
#Override /** Clear the list */
public void clear() {
size = 0;
head = tail = null;
}
#Override /** Override iterator() defined in Iterable */
public ListIterator<E> listIterator() {
Node<E> current = head; // Current index
return list.listIterator();
}
#Override /** Override iterator() defined in Iterable */
public ListIterator<E> listIterator(int index) {
Node<E> current = head; // Current index
for (int i = 0; i < index; i++) { // sets current int to the parameter
current = current.next;
}
return list.listIterator();
}
#Override
public int size()
{
return size;
}
public class Node<E> {
E element;
Node<E> next;
Node<E> previous;
public Node(E element) {
this.element = element;
}
}
}
This is my original class, I will include my test case below but first let me explain my problem. I am trying to create a Doubly linked list and iterate backwards through it. However I am getting a Null Pointer Exception by just adding elements to the list. I have looked over the section of code for my addFirst method for about 2 hours now and don't see any logic errors(doesn't mean there arent any), please help!
Here is my test case as promised.
public class TestMyLinkedList {
/** Main method */
public static void main(String[] args) {
// Create a list for strings
MyTwoWayLinkedList<String> list = new MyTwoWayLinkedList<String>();
// Add elements to the list
list.add("America"); // Add it to the list
System.out.println("(1) " + list);
list.add(0, "Canada"); // Add it to the beginning of the list
System.out.println("(2) " + list);
list.add("Russia"); // Add it to the end of the list
System.out.println("(3) " + list);
list.addLast("France"); // Add it to the end of the list
System.out.println("(4) " + list);
list.add(2, "Germany"); // Add it to the list at index 2
System.out.println("(5) " + list);
list.add(5, "Norway"); // Add it to the list at index 5
System.out.println("(6) " + list);
list.add(0, "Poland"); // Same as list.addFirst("Poland")
System.out.println("(7) " + list);
// Remove elements from the list
list.remove(0); // Same as list.remove("Australia") in this case
System.out.println("(8) " + list);
list.remove(2); // Remove the element at index 2
System.out.println("(9) " + list);
list.remove(list.size() - 1); // Remove the last element
System.out.print("(10) " + list + "\n(11) ");
for (String s: list)
System.out.print(s.toUpperCase() + " ");
list.clear();
System.out.println("\nAfter clearing the list, the list size is "
+ list.size());
}
}
I'm not completely sure why you are using a LinkedList within your own implementation of a Double Linked List. In regards to your question about your addFirst method however, I have the following comments and an example of how I would approach this solution.
Head is null when you call the addFirst method.
Head has not been initialized as a new Node.
Therefore newNode.next = head; is actually newNode.next = null; There is your null pointer exception, I would imagine!
public void addFirst (E e)
{
Node<E> newNode = new Node<E>(e); //create new node
if (head != null){ //if head exists
newNode.next = head; //the new node's next link becomes the old head
}
head = newNode; //the new head is the new node
if (tail == null){ //if the tail is non existent ie head the only object in list
tail = head; //the head and the tail are the same
head.next = tail; //the 'next' value of head will be tail
}
head.prev = tail; //the previous node to head will always be tail
size++;
}
}