Displaying ArrayList objects? - java

I've got an ArrayList full of LinkedLists and I need to be able to display specific linked lists within that arraylist.
for(int i=0;i<my_lists.size();i++){
System.out.println(my_lists.get(my_lists.size()));
}
This is displaying in output :
kruskal.LinkedList#a4aad7f
kruskal.LinkedList#2cc47220
kruskal.LinkedList#1520a9d6
kruskal.LinkedList#136e2b70
kruskal.LinkedList#25e5d007
kruskal.LinkedList#12bc8f01
kruskal.LinkedList#19509443
as my output. Why is it not displaying my Linked Lists?
Here's my LinkedList class:
package kruskal;
public class LinkedList {
Node head;
public LinkedList(){
this.head = null;
}
public void add (Object newData){
Node cache = head;
Node current = null;
if (cache == null)
current = new Node(newData, null);
else {
while ((current = cache.next) != null)
cache = cache.next;
cache.next = new Node(newData,null);
}
}
public Object getFront(){
return this.head.data;
}
}

Since LinkedList is an object, when you print the object using System.out.println, the toString() method is called. Since your class does not have a toString() method, its parent class' toString() is called, which in this case is most probably Object.
So you need to override the toString() method in your LinkedList class and print the object in the way you want.

In your code this line my_lists.get(my_lists.size()) must give you error of because you are reading a object at index my_lists.size() which never exist and give error like Index Out of bounds exception.
You need to read your LinkedList in loop inside your for loop.
for(int i=0;i<my_lists.size();i++){
LinkedList link = my_lists.get(i)
//Read value from LinkedList here
for(int j=0;j<link.size();j++){
//I dont know what type of object stoer in your linked list so i get it in Object
Object obj = link.get(j); //read your value here as per data type stored.
System.out.println(obj);
}
}

The problem is you haven't overridden the toString() method in your LinkedList class.
Override toString() and have it iterate through the list returning a CSV of the toString() values of each element (like the implementation of java.util.LinkedList)

Related

Iterator stack hasNext() not returning true

I'm trying to iterate over an Object array. Using the next() method works so I'm guessing that my iterator class and constructors are working.
For some reason i'm not getting any output while the hasNext() method is running.
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
With "hej" being my Object array.
My code for the next(); and hasNext() methods are as follows:
public class StackIterator implements Iterator<Object>{
// fields
private int element = 0;
private final Object[] elements;
private final int max;
// constructor
public StackIterator(Object[] values, int maxIndex) {
elements = values;
max = maxIndex;
}
// methods
public boolean hasNext() {
return element < max;
}
public Object next() {
return elements[element++];
}
}
The file that constructs the Object Array and the Object Array depends on an interface:
public interface Stack {
int size();
boolean isEmpty();
void push(Object element);
Object pop();
Object peek();
Iterator<Object> iterator();
}
The methods are then explained in another file:
public class StackExample implements Stack {
// fields
int length = 0;
Object[] arr;
// constructor
public StackExample() {arr = new Object[length];}
// method returns size of object array
public int size() {
return arr.length;
}
// method checks if object is empty
public boolean isEmpty() {
boolean result = false;
if (arr.length == 0){
result = true;
}
return result;
}
// method for push
public void push(Object element) {
newBiggerObj();
arr[0] = element;
}
// returns the first object of the stack
public Object pop() {
Object[] temp = new Object[arr.length-1];
Object first = arr[0];
for (int i = 0; i<arr.length-1; i++){
temp[i] = arr[i+1];
}arr = temp;
return first;
}
// returns the object on top of stack
public Object peek() {
if (isEmpty()){
try{
throw new Exception("Stack empty, can't peek!");
}
catch(Exception e){
return e.getMessage();
}
}
else {
Object first = arr[0];
return first;
}
}
// method for push method
private void newBiggerObj(){
Object[] temp = new Object[arr.length+1];
for (int i = 0; i<arr.length; i++){
temp[i+1] = arr[i];
}
arr = temp;
}
public String toString(){
String str = "";
for (int i = 0; i < arr.length; i++){
str = str + arr[i] + " , ";
}return str;
}
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
}
What bothers me is that the method Iterator is within itself returning an instance of the class Stack Iterator. Which i posted above. So my real problem seems to be that my fields are not being given any value, since I am not myself giving the any values within the constructor.
My main method in which I'm testing all of this is as follows:
public class Teststack {
public static void main(String[] args){
// new instane of class StackExample
StackExample hej = new StackExample();
// test for the different methods
System.out.println(hej.isEmpty());
System.out.println(hej.size());
hej.push(4);
hej.push("hej");
hej.push(6);
hej.push(5);
System.out.println(hej.size());
System.out.println(hej.peek());
System.out.println(hej.pop());
System.out.println(hej.toString());
System.out.println(hej.isEmpty());
System.out.println("Testing Iterator: ");
// test for iterator
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
}
}
In your StackExample class, I don't see the length variable being updated when elements are pushed or popped. Due to this, length will always be 0 and calls to it.hasNext() will always return false.
You don't need to pass the length as a separate argument. You can find the array's length in the StackIterator constructor and use it.
Also note that since you're creating a new array on every push and pop, the iterator returned by StackExample#iterator() will become stale after every push/pop since it will work on an old copy/state of the stack.
The problem is here:
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
length field is never changed, so its value is always 0. You can change the code to this:
public Iterator<Object> iterator() {
return new StackIterator(arr, arr.length);
}
Also, before retrieving elements from the iterator, you should always call it.hasNext. The fact you did this:
Iterator it = hej.iterator();
Object j = it.next();
And worked was just pure luck.
Apart of this, I can sense you have a bad design on your stack implementation. Here are some hints to improve your code:
The inner array should be initialized with a default size different than 0. E.g. 10 (as done in java.util.ArrayList implementation).
You should avoid creating a new array when adding (push) or removing (pop) an element from your stack. Instead of this, you should use the length field to control how many elements are in your stack.
The value of the new size should be based on another formula rather than array.length + 1. For example, try using something like int newSize = array.length / 2 * 3;.
Resize the inner array only when necessary. When calling push, do it only if you precisely need to increase the size of the array. When calling pop, do it if the current length of the array (this is, array.length) is far greater than the value of length field of your class.
Never forget to update the value of length on push and pop methods.
Couple of issues:
You are calling Object j = it.next(); after creating iterator and then check for hasNext. You are incrementing the element index. Hence if you just have one element, you wont enter the while loop. In addition, if your custom datastructure is empty i.e. array has no elements then you are prone to ArrayIndexOutOfBoundException.
You will always iterate and print n-1 elements instead to n elements.
Once you iterated, then your pointer will always point to last element and never get resetted. So very next time you wont be able to iterate over your elements. Its a one time iterator.
Try not to call
Object j = it.next() statement, but just while cycle. Seems you have an array of just 1 element.
There are a number of problems with this code:
In the StackIterator constructor there is no bounds checking on maxIndex. Callers can pass in a number greater than values.length, less that 0, etc.
In the next method, there is no check of the end condition, either directly or by calling hasNext(). Callers can keep calling next() and see elements beyond max or even get an ArrayIndexOutOfBoundsException, when they should be getting a NoSuchElementException.
The Stack class never increments or decrements its length field when elements are pushed or popped.
The Stack class tracks the length separately from the array, even though it always resizes the array on every push or pop, but Java arrays already know their size. (But see the next item.)
The Stack class resizes the array on every push or pop, which is very inefficient. Typically classes like this only resize the array when necessary, allowing 'slack' space, to give amortized constant time performance (see ArrayList). If you do this, however, it is necessary to null out popped items to avoid unintentional object retention.
The Stack adds and removes elements at the beginning of the array. This is incredibly inefficient since it means a O(n) reshuffling must be done on every push or pop.
The peek() method takes into account the possibility that the Stack may be empty, but the pop() method does not. A pop() on an empty Stack will throw an ArrayIndexOutOfBoundsException.
Stack is not a generic class. It holds Object. Users of the Stack will have to cast the return values from peek() or pop(), and it isn't type safe. In your example, you show a stack that is a heterogeneous mixture of String and Integer. This is a very Java 1.2 way of doing things, and while it isn't necessarily wrong, you should consider parameterizing Stack.

Java Iterable object won't Iterate correctly

I have a java object that implements the Iterable interface. This linked list has a group of objects that each hold a parameterized object (so it could be a String OR an ArrayList or whatever).
In the iterator() method, i create an Iterator object that takes an array of these parameterized items and return it.
However, when i use the following code:
//create an Iterable object named 'iterate'
for(String current : iterate){
//try to do some stuff with it... print it out?
}
//more code
//here is how i implemented the iterator function of my Iterable class:
public Iterator<Item> iterator(){
// return an iterator over items in order from front to end
Item[] items = (Item[]) new Object[numberOfItems];
QueueItem<Item> item = first;
for(int i=0;i<numberOfItems;i++){
items[i] = item.getInfo();
item = item.next;
}
return new myIterator(items);
}
//here is the code for the myIterator class. it is a private internal class
private class myIterator implements Iterator<Item>{
Item items[];
int index;
public myIterator(Item current[]){
items = current;
index = 0;
}
#Override
public boolean hasNext() {
if(items==null){
return false;
}
return (index>=items.length);
}
#Override
public Item next() {
if(index+1>=items.length){
throw new NoSuchElementException("There are no more elements!");
}
return items[index++];
}
#Override
public void remove() {
throw new UnsupportedOperationException("this operation is not supported");
}
}
the code goes to the for loop, then creates the Iterator object correctly (I used breakpoints to confirm), and returns it, but then the code jumps out of the for loop without going through it even once and continues....
Am i missing something? did i do something wrong here? how do i need to change the implementation of my Iterable object? is there some GOTCHA with implementing this that i'm not taking into account?
thanks!
in hasNext method you check if return (index>=items.length); Well this will return false. change operant to "<"
oh my gosh. so embarrassing. the hasNext method had the boolean statement reversed.
it should have been:
return (index<items.length); thanks anyways!
i've been pulling my hair out about this. i debugged everything else, then it dawned on me.
This is my first iterator implementation, so i figured it must have been something more fundamental that i wasn't doing correctly.

Confused about linked list deletion

I am trying to implement the deletion function in
public static boolean delete(Object d, ListElement head){
ListElement p=find(d,head);
if(p.data==null){return false;}
else {
System.out.println("Delete Successfully!");
if(head.data==d){head=head.next;}
else{
while(head.next.data!=d){
head=head.next;
}
head.next=head.next.next;}
return true;}
}
This function basically check if the element d is in the list,
-if not->return false;
-else check whether the element is the first element of the list, if true, change the head to its next,
-else traverse to the list element in front of it.
The problem is case the element to delete is the first element, such as boolean s=ListElement.delete(1,d); I cannot use "head=head.next;" to assign new value to head. But java is passed by reference, why cannot I change that?
//actually I found my question is whether we can change the reference passed to the function inside the function
like:
void fun(dog a){
a=new dog("Po");
}
main()
{dog b=new dog("Jo");fun(b);}
//so will b be changed?
The reference to the first list element is either held by the list object itself or by an "invisible" root element (in case of single linked list).
So you either have to pass the entire list to the method or, if you have that invisible root, pass the root as head.
public static boolean delete(Object d, MyLinkedList<ListElement> list) {
ListElement head = list.getHead();
if (head.data.equals(d)) { // <- ALWAYS use equals, never == to compare objects!!
list.setHead(head.next);
} else {
ListElement element = head.next;
// ... the rest is similiar to your algorithm
}
}
The Java Pass by Reference idea means, that when you call a method, and give some object as an argument, you'll get a new reference pointing to the same object.
Altering values, will change the object, in turn also affecting other references. But if you give a new value to the parameter, only that will be changed, to point to some different object. (It's worth mentioning that there are languages that do allow changing the argument, to change the first passed parameter.)
void delete(visit_ptr_node_type this_is_the_node)
{
visit_ptr_node_type one_back;
if(anchor == NULL)
printf("\n The list is empty");
else
{
if(this_is_the_node==anchor)
anchor=anchor->next_ptr;
else
{
one_back=anchor;
while(one_back->next_ptr != this_is_the_node)
one_back=one_back->next_ptr;
one_back->next_ptr = (this_is_the_node) ->next_ptr;
}
free(this_is_the_node);
}
}

Sorted linked list implementation

i am a novice programmer, to be specific, i am learning java programming and i am supposed to implement sortedLinkedList class that extends LinkedList class from the java library. The list has to store persons in ascending order of their surnames. I have already written my Person class that implements Comparable interface. my problem is, I have been struggling implementing this sortedLinkedClass but to no avail. My code runs without any compiling or run time error but the program does not print anything. Another thing as you can see , I am testing it with Integers instead of Persons and it throws NullPointerException when trying to add a number that is already in the list. My code is as it is below.
import java.util.*;
public class SortedLinkedList< E> extends LinkedList<E>
{
private Link<E> first;
private Link<E> last;
/**
* Constructor for objects of class SortedLinkedList
*/
public SortedLinkedList()
{
//super();
first = null;
last = null;
}
/*
* Link class for creating Link nodes in the SortedLinkedList objects
*/
private class Link<E>
{
public Comparable<E> data;
public Link next;
}
/*
* Overiding add method from LinkedList class
*/
public boolean add(E obj)
{
Link newLink = new Link();
newLink.data = (Comparable<E>)obj;
// When the list is initially empty
if (first == null)
{
first = newLink;
last = newLink;
return true;
}
// When the element to be added is less than the first element in the list
if (newLink.data.compareTo(first.data) < 0)
{
//newLink.data = obj;
newLink.next = first;
first = newLink;
return true;
}
// When the element to be added is greater than every element in in list
// and has to be added at end of the list
if (newLink.data.compareTo(last.data) > 0)
{
//newLink.data = obj;
last.next = newLink;
last = newLink;
return true;
}
//When the element to be added lies between other elements in the list
if (newLink.data.compareTo(first.data) >= 0 && newLink.data.compareTo(last.data) <= 0)
{
//newLink.data = obj;
Link current = first.next;
Link previous = first;
while (newLink.data.compareTo(current.data) <= 0)
{
previous = current;
current = current.next;
}
previous.next = newLink;
newLink.next = current;
}
return true;
}
public static void main (String[] args)
{
LinkedList<Integer> list = new SortedLinkedList<Integer>();
list.add(4);
list.add(5);
list.add(10);
list.add(9);
//list.add(5);
ListIterator<Integer> iterator = list.listIterator();
while (iterator.hasNext())
{
System.out.println(iterator.next());
}
}
}
If you must use a LinkedList, all you really have to do is override the "add" method so that it inserts your element in the correct position. You can do that by invoking the add(integer,Object) method which inserts your element in a specific position.
Here's a quick and dirty (and non-generic :P) implementation of what I'm talking about.
public class PersonLinkedList extends LinkedList<Person> {
public boolean add(Person personToAdd) {
int index = 0;
for( ; index<size() ; index++){
Person personAlreadyInList = get(index);
if(personToAdd.compareTo(personAlreadyInList) < 0){
break;
}
}
add(index, personToAdd);
return true;
};
public static void main(String[] args) {
Person amy = new Person("Amy");
Person bob = new Person("Bob");
Person claire = new Person("Claire");
PersonLinkedList list = new PersonLinkedList();
list.add(bob);
list.add(claire);
list.add(claire);
list.add(amy);
list.add(bob);
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Person person = (Person) iterator.next();
System.out.println(person);
}
}
}
class Person implements Comparable<Person>{
private String name;
public Person(String name) { this.name = name; }
public String getName() { return name; }
#Override
public String toString() { return getName();}
#Override
public int compareTo(Person p) {
return name.compareTo(p.name);
}
}
The reason nothing gets printed is because you store the data in your own linked list data tree and not the LinkedList's data tree. You don't override the iterator method, so the iterator will loop through LinkedList's data which is empty. This is also a problem with all the other methods in LinkedList.
Are you sure you need to inherit from the LinkedList class or are you suppose to make your own class.
If you are supposed to inherit from LinkedList get rid of you node and use LinkedList for storing the data. Your add method would then use a ListIterator to find the correct spot for adding and use the add method of ListIterator.
If you don't inherit from LinkedList then extend AbstractSequentialList.
Note:
Both of these options should not be used in real code. Adding automatic sorting breaks the List interface.
The whole problem is a perfect example of "prefer composition over inheritance".
If this is homework do it as instructed, otherwise I'd recommend changing the exercise to implement a SortedCollection backed by a LinkedList. Then implement Collection and use a List as a member variable.
You could use a SortedSet if you don't need to support elements with the same sort key.
Also, the reason your code doesn't print anything is because you override adding items to the list, but not iterating (the iterator() or listIterator() methods.) Extending LinkedList doesn't automagically make your data structure iterable unless you modify its contents using the base class add(), remove(), and other methods.
besides iterator, add/remove override, I think your algorithm to sort is not correct. And that leads to the nullpointer exception when you add existing elements into your "sortedLinkedList".
while (newLink.data.compareTo(current.data) <= 0)
{
previous = current;
current = current.next;
}
I think what you wanted is while (newLink.data.compareTo(current.data) >0) . not <=0. here is the mistake.
since "=0" is in while condition, it will go through the whole list, till the last element, then execute:
(current is the last now)
previous = current;
current = current.next; (now, current is Null, since last.next is Null)
finally, current is Null, then comes again, current = current.next; Bang! Nullpointer.
so I guess the Nullpointer was thrown at this line.

How do I refer to the current object in an iterator

I am trying to implement a search method in a TreeSet. By using an iterator with a condtional I would like to be able to run through the set and print the object that matches the condition. However the way I am doing it at the moment is printing out the subsequent object rather than the current.
This is what I have so far:
public void getDetails() {
Iterator<Person> it = this.getPersonSet().iterator();
System.out.println("Enter First Name");
String first = in.next().toLowerCase();
System.out.println("Enter Second Name");
String last = in.next().toLowerCase();
while (it.hasNext()) {
if (it.next().getLast().toLowerCase().equals(last)) {
Person p = it.next();
System.out.println(p);
}
}
}
Any help would be great
This is what you would want to do:
while (it.hasNext()) {
Person p = it.next();
if (p.getLast().toLowerCase().equals(last)) {
System.out.println(p);
}
}
How do I refer to the current object in an iterator
For the record, the Iterator API does not allow you to do this. There is no notion of a "current" object. The Iterator.next() method gives you the next object ... and moves on.
(The ListIterator.previous() and ListIterator.next() methods are analogous. Note that in the ListIterator case, method behaviour is documented in terms of a cursor that denotes a position before / between / after elements in the sequence being iterated.)
The solution is to assign the result of calling it.next() to a temporary variable, as described by the accepted answer.
I don't know for sure why the designers didn't include the notion of a "current" object in the API, but I can think of a few reasons:
It would make a typical1 Iterator object bigger; i.e. an extra field to hold the current object.
It would mean 1 extra method for an Iterator class to implement.
The notion of a current object does not fit well with the "cursor" model documented in the ListIterator interface ... and implied by the current Iterator design.
There is the issue of the Iterator "hanging onto" the current object. In some cases that will prevent from being GC'ed.
The large majority of iterator use-cases don't require a current object.
Also, there are other ways to deal with this.
Sounds like a good call ...
1 - This and other points don't apply equally to all implementations of the Iterator API. Indeed, in some cases the implementation of current() will be simple. But that is beside the point. Unless you make the proposed current() method an optional2 method (like remove()) every iterator implementation ... and by extension, every Map and Collection class ... has to provide this functionality, and deal with the issues, one way or another.
2 - Optional methods come with their own problems.
If you need an existing implementation, you can use the ones from Google Guava or Apache Commons Collections.
The other answers are easier for your simple problem, but if you need to pass the iterator around and keep track of the last item returned by next(), these would help.
Here is an example using Guava with the OP's code (assumging Person indeed has a String toLowerCase() method):
import com.google.common.collect.PeekingIterator;
import static com.google.common.collect.Iterators.peekingIterator;
public void getDetails() {
PeekingIterator<Person> it = peekingIterator(this.getPersonSet().iterator());
System.out.println("Enter First Name");
String first = in.next().toLowerCase();
System.out.println("Enter Second Name");
String last = in.next().toLowerCase();
while (it.hasNext()) {
// note the usage of peek() instead of next()
if (it.peek().getLast().toLowerCase().equals(last)) {
Person p = it.next();
System.out.println(p);
}
}
}
Hold the reference of the object in a separate var:
Person current = it.next();
current.methodOne();
current.methodTwo();
When you're done with the current value, re-assing it the next
...
// done?
current = it.next();
In a loop looks like:
while( it.hasNext() ) {
Person current = it.next();
current.doA();
current.doB();
current.doC();
}
the next() method returns the current object, like this:
private class IterSinglyLinked implements SimpleIterator<T> {
Element curr = head; // next element to return
public boolean hasNext() {
return curr != null;
}
public T next() throws Exception {
if (curr == null) throw new Exception("no more elements");
T data = curr.data;
curr = curr.next;
return data;
}
}
If it returns the next one rather than the current one, there will be no way to reach the very first one

Categories