Getting list values using Iterator Java - java

I'm trying to use a list iterator to walk a linked list and do some operations / checks on the next node depending on the integer value stored there, but I'm getting some errors in my code. I think I'm not understanding what iterator.next() is returning (some E object, but I don't know how to access the value I want from it) The editor wants me to do some casting as explained below. It gets rid of errors, but I don't know if this is a safe way to handle the problem or if it has the behavior I'm looking for. Please explain why I am getting errors and if there is a good way to handle this.
LinkedList<Integer>[] hash = new LinkedList[list.size()];
hash = remo.createHash(hash, list.size());
ListIterator iterator = list.listIterator(0);
// use the value of the integer stored at the next Node as its hash
// and add the same value to the linked list at that bucket
int i = 0;
while(iterator.hasNext()){
hash[iterator.next()].add(iterator.next());
i++;
}
// reset iterator to beginning of list
iterator = list.listIterator(0);
// if the hash bucket corresponding to the value at that node has more than
// one item in its list, remove that node from the list.
while(iterator.hasNext()){
if(hash[iterator.next()].size()>1){
iterator.remove(iterator.next());
}
}
createHash initializes each linked list in the array and remo is an instance of my class.
the editor wants me to cast iterator.next() to an int hash[iterator.next()] and it wants me to cast it to an in .add(iterator.next()).
Example:
hash[(int)iterator.next()]
hash[(int)iterator.next()].add((Integer)iterator.next());

LinkedList<Integer>[] hash = new LinkedList[list.size()];
This line is problematic due to http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#createArrays
You cannot create arrays of parameterized types. For example, the following code does not compile:
List<Integer>[] arrayOfLists = new List<Integer>[2]; // compile-time error
Because:
Object[] stringLists = new List<String>[]; // compiler error, but pretend it's allowed
stringLists[0] = new ArrayList<String>(); // OK
stringLists[1] = new ArrayList<Integer>(); // An ArrayStoreException should be thrown,
// but the runtime can't detect it.
If arrays of parameterized lists were allowed, the previous code would fail to throw the desired ArrayStoreException.
As such, you are creating an array of lists that aren't using generics (as you cannot create arrays of parameterized types), and as such, it stores Objects (it doesn't know what type you're actually planning to store). You should probably use an ArrayList instead of an Array to fix this problem, like so:
List<List<Integer>> listOfLists = new ArrayList<List<Integer>>(list.size());
//example usage
listOfLists.add(new LinkedList<Integer>());
for(List<Integer> currList : listOfLists)
{
...
}

Arrays and generics don't mix. Just use a List<List<Integer>>:
List<List<Integer>> hash = new LinkedList<List<Integer>>(list.size());

Related

Java: how to create a list cons that accepts lists for the first element

When I create a Java list and I want that the head is a list, should it print a [[-1,0],1,2,3,4] or its alright it just leave the sublist [-1, 0] as two separated elements like [-1, 0, 1, 2,3,4] and, how can I get the first structure as an aswer.
From your post I guess you are asking about how to create a list "construct" in Java which contains both list and non-list elements.
In Java all elements of your list/array need to have the same type. In the example you posted ([[-1,0],1,2,3,4]), the elements are not all the same type. What you have is this: [List<Integer>, Integer, Integer, Integer, Integer]. The first one is different, which isn't allowed in Java.
So, what you need to do is make it so that all elements of your list/array are the same type.
For your case, where there are only integers in your list, the easiest thing to do is to change your types to this: [List<Integer>, List<Integer>, List<Integer>, List<Integer>, List<Integer>] (with your specific values: [[-1,0],[1],[2],[3],[4]]). Instead of a list of List<Integer> and Integer, you now have a list containing only List<Integer> (some of your lists happen to contain only 1 element, but that is ok).
This is called a "two-dimensional list" and depending on whether you want to code it with arrays or java.util.Lists you can code it in one of the following ways:
// with arrays
int[] myTwoDarr = int[5][];
myTwoDarr[0] = new int[]{-1, 0};
myTwoDarr[1] = new int[]{1};
myTwoDarr[2] = new int[]{2};
myTwoDarr[3] = new int[]{3};
myTwoDarr[4] = new int[]{4};
// With Lists
List<List<Integer>> myList = new LinkedList<>();
List<Integer> nestedList1 = new LinkedList<>();
nestedList.add(-1);
nestedList.add(0);
myList.add(nestedList1);
List<Integer> nestedList2 = new LinkedList<>();
nestedList2.add(1);
myList.add(nestedList2);
...etc...
Now, if you absolutely must have different kinds of data in your list, you can create a list of Object instead.
In Java Object is a type from which all non-primitive types inherit. Thus, as long as something is not a primitive, it is an Object and can go in a list of Object. This will allow you to put any kind of data in the elements of your list. Using Object allows you to have a list of all the same type which looks like this: [Object, Object, Object, Object, Object]. But, now Java does not know the specific types you actually have stored in your elements so you will need to type cast when getting them.
Here's an example using a java.util.List:
List<Object> myList = new LinkedList<>();
List<Integer> nestedList = new LinkedList<>();
nestedList.add(-1);
nestedList.add(0);
myList.add(nestedList);
myList.add(1);
myList.add("a string");
// You need to cast when taking elements out of the list.
List<Integer> newNest = (List<Integer>) myList.get(0);
Integer myInt = (Integer) myList.get(1);
String myString = (String) myList.get(2);
Since all your base data types are the same (Integer/int) I recommend avoiding the Object list method and going with the 2D list. It's simpler and less error prone to not do all this casting.

Array of generic holders

If I have a map of Entry .. objects , and I have an array in a class
private Entry<K,V> array;
Can I say
array = new Entry[someInt];
which I've done, or do I need a typecast like my instructor says is necessary such as
array = (Entry<K,V> E[]) new Entry[someInt];
Note that the first one did work when I ran my JUnits.
Have you thought about doing a List ?
Entry<K,V> array = new ArrayList<Entry<K,V>>();
array.add(new HashMap<K,V>());
You can do either one. Implicit conversions to and from raw types are allowed without a cast.
array = new Entry[someInt]; will produce an unchecked conversion warning.
array = (Entry<K,V>[])new Entry[someInt]; will produce an unchecked cast warning.
So neither one is really better than the other.
Note that if you create the array with the wildcard type, you will need to have a cast:
array = (Entry<K,V>[])new Entry<?,?>[someInt]; // compiles
array = new Entry<?,?>[someInt]; // doesn't compile

ConcurrentModificationException at for each android

I am passing Arraylist of ParseObject, and then i am putting one one foreach loop to extract the items with a condition when user object is not equals to null. There are two problems which i am facing.
1. If i am doing the following lines of code by passing different data to another list and then pass that list in my adapter, i am getting random data with numbers for example: If on item # 1 the name is "MAC" then it is showing in item 3.
ArrayList<ParseObject> checkRequestedNetArrayList = new ArrayList<ParseObject>();
requestedNetArrayList = (ArrayList<ParseObject>) objects;
MyResponsibilitesActivity.requestedNetArrayList = requestedNetArrayList;
adapterRequest = new GenericAdapter<ParseObject>(
getApplicationContext(),
requestedNetArrayList,
R.layout.requested_trust_net_list_item,
requestedDataBinder);
requestListView.setAdapter(adapterRequest);
requestedNetArrayList = (ArrayList<ParseObject>) objects;
for(ParseObject object: objects){
System.out.println(object);
object.getParseObject("user");
if(object.has("user")){
checkRequestedNetArrayList.add(object);
}else{
checkRequestedNetArrayList.remove(object);
}
}
adapterRequest = new GenericAdapter<ParseObject>(
getApplicationContext(),
checkRequestedNetArrayList,
R.layout.requested_trust_net_list_item,
requestedDataBinder);
requestListView.setAdapter(adapterRequest);
If i am doing the following line of code to just direct giving the items in the same list, i am getting the java.util.ConcurrentModificationException
for(ParseObject object: objects){
if(object.has("user")){
requestedNetArrayList.add(object);
}
}
else{
requestedNetArrayList.remove(object);
}
adapterRequest = new GenericAdapter<ParseObject>(
getApplicationContext(),
requestedNetArrayList,
R.layout.requested_trust_net_list_item,
requestedDataBinder);
requestListView.setAdapter(adapterRequest);
}
Please help me out here.
You can not remove an element from list while accessing it.
You have to use Iterator.
Where ever you are removing the object, use it.remove();
Iterator<ParseObject> it = objects.iterator();
while(it.hasNext()){
Object object = it.next();
//your stuff
it.remove();
}
I think you might want to check this article about deep copy also.
UPDATE
Since you want to add elements to the list it is not directly possible with iterator. Now you are facing problem because you are directly assigning objects to requestedNetArrayList instead of that do it in the following way :
ArrayList<ParseObject> requestedNetArrayList = new ArrayList<>(objects);
Then iterate over objects as you are doing now, and remove from or add to
requestedNetArrayList (which you are pretty much already doing).
When you make iteration using for-each construction for Collection
for (Object x : collection) ...
you have implicit creation of Iterator object for that Collection. This iterator performs a check: is collection was changed since iterator was created? If so, throwing an exception. So, you should avoid to any modify to your collection, until iterator done. That means, you should not use add and remove.
In either way, it is better to access ArrayList by index, because it will prevent creation of Iterator object. Like this:
for (int i = objects.size() - 1; i >= 0; i--) {
ParseObject object = objects.get(i);
// when iterating from tail to head, you can safely add or remove objects to/from this array list
}
Instead of assigning the reference of objects to requestedNetArrayList,
create a new ArrayList with the same contents
requestedNetArrayList=new ArrayList<ParseObject>(objects);
Then you can iterate on objects and modify requestedNetArrayList.

Java - Casting, Generics, Objects and Arrays

I was wondering if it is possible to convert an Object into something else.
I have a Object which contains a series of numbers in a random order such as: 3, 4, 2, 5, 1 and wondering if I am able to turn it into an int[] or select certain elements from it, as in a number from the sequence?
EDIT:
so some of the code i have is:
//This contains all the different combinations of the numbers
ArrayList routePop4 = new ArrayList();
//This picks out the first one, just as a test
Object test = routePop4.get(0);
But the idea is that I want to loop through each element of test.
An Object cannot "contain a series of numbers". However many subclasses of Object, such as all of the Collections can "contain a series of numbers", and they come with a toArray() method to turn the contents of the collection into an array.
If you have a collection, but only have access to it as an Object, you need to cast it before you can work with it properly:
ArrayList<Integer> list = (ArrayList<Integer>)test;
Integer[] arr = list.toArray(new Integer[]{});
It's fairly rare in day-to-day Java to actually be working with variables cast as Object, if you are, it should be a red flag that you may be doing something wrong. You can use generics to allow objects that contain other objects to do so generically, like so:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1); // Can only add integers, list.add("a string") would fail at compile time
int n = list.get(0); // no need to cast, we know list only contains Integers
If you aren't using a Collection, you'll presumably need to roll your own, as Luke Taylor's answer suggests. That said, you'll get better answers if you can provide more information, the current text of your question doesn't make sense in a Java context.
After seeing your edit, I recommend taking advantage of generics.
When you declare an ArrayList you can indicate what kind of objects it's going to contain.
For example, if you know your ArrayList will contain Strings, you would do this:
List<String> myList = new ArrayList<String>();
If each element of your list is an array of Integers, you would do this:
List<Integer[]> listOfIntegerArrays = new ArrayList<Integer[]>();
Then you could get any element from your list and assign it to an Integer array like this:
Integer[] integerArray = listOfIntegerArrays.get(0);
Then you could iterate over every Integer in the list like this:
for (Integer loopInteger : integerArray) {
System.out.println("The value: " + loopInteger);
}
Some more reading on generics:
http://thegreyblog.blogspot.com/2011/03/java-generics-tutorial-part-i-basics.html
http://docs.oracle.com/javase/tutorial/java/generics/
You could do something like this:
int[] numbersFromObject = new int[yourObject.getAmountOfNumbers()];
// Initialize array with numbers from array
for(int i = 0; i < yourObject.getAmountOfNumbers(); i++) {
numbersFromObject[i] = yourObject.getNumber(i);
}
I'm not sure what methods your object contains, yet I'm sure you'll be able to adjust to the following mentioned above.
I hope this helps.

Java ListIterator/Iterator Type

I have a code snippet as shown below:
ArrayList<Integer> a = new ArrayList<Integer>();
ListIterator<Integer> p = a.listIterator();
However, I noticed that you don't really need to specify the for the ListIterator so the code works same without it:
ArrayList<Integer> a = new ArrayList<Integer>();
ListIterator p = a.listIterator();
I think the same is als true for Iterator. So my question is when do I have to specify the type for a ListIterator/Iterator ? Is it something optional that can be used be more verbose ?
The reason to specify the generic type for the iterator is so you can extract the item it retrieves without casting. This adds a bit of compile-time type safety with no additional significant overhead, so I see no reason not to do this.
What you are referring to, is called generics. It's a really powerful tool, which - amongst others - gives you type safety for collections in compile-time.
Take a look at Java Denerics documentation pages to learn when, why and how you should use them.
Now, back to your example - this code:
Iterator it1 = a.iterator();
Iterator<Integer> it2 = a.iterator();
it1.next(); // Compiler will assume, that this returns `Object`
// because you did not define the type of the collection element
// for the Iterator.
it2.next(); // Compiler will assume, that this returns `Integer`
// because you said so in declaration.
The purpose of providing a type argument for an Iterator< T >/List< T > is type-safety ,i.e. the compiler can check at compile time if there is a mismatch between the type the iterator/list can handle and what the programmer expects it to handle.
Ex:
List aList = new ArrayList();
Iterator it = aList.iterator();
String s = (String)it.next() //compiles even if it iterates over a list of Integers
List<Integer> aList = new ArrayList<Integer>();
Iterator<Integer> it = aList.iterator();
String s = it.next() //compilation error

Categories

Resources