Object assignment via iterator in Java - java

I have a piece of code like this:
HashSet<Object> Set = new HashSet<Object>();
//add elements to set 'Set'
Object o = null;
for (Iterator<Object> itr=Set.iterator();itr.hasNext();) {
o = itr.next();
//doing some processing on o
}
I assumed that Object o will point to the Object pointed to by itr. But it is not working as expected. The attributes pointed to by itr.next() is not being copied to o.
Can anybody suggest where I am going wrong? And also, is there some useful post on object assignment like
o1 = o2
and what happens at memory level in Java?
Below is my actual code:
What I am doing: I have created a set TSet of elements of type Types.AdjList and now I want to process each successive pair of elements of type Types.AdjList and have assigned iterator value during each iteration to two Types.AdjList variables T1 and T2. But T1 and T2 attributes are not matching what the iterator is having.
P.S. Types.AdjList is a HashMap
for (int i=0; i<numT; i++) {
size = generator.nextInt(10)+1;
T[i] = new Types().new AdjList(size);
}
HashSet<Types.AdjList> TSet = new HashSet<Types.AdjList>();
for (int i=0; i<T.length; i++) {
TSet.add(T[i]);
}
Types.AdjList T1 = null, T2 = null;
for (Iterator<Types.AdjList> itr = TSet.iterator(); itr.hasNext();) {
T1 = itr.next();
if (T2 != null) {
size1 = T1.adj.size();
//size1 is returning 0, though T1.adj has some elements
size2 = T2.adj.size();
//do some processing on T1, T2 based on size1 and size2
}
T2 = T1;
}
Any help will be appreciated.
Thanks,
Somnath

There is nothing wrong with your code, but it could use some cleaning up.
If you apply these "best practice" coding standards:
Always declare the abstract type (ie Set not HashSet)
Use leading-lowercase names for variables (set not Set)
Use "foreach" syntax where possible (dispense with using iterators directly)
Declare variables so they have the smallest scope possible (o lived past its use)
you get your code refactored to:
for (Object o : new HashSet<Object>(someSet)) {
// doing some processing on o
}
or even
for (Object o : someSet) { // Not sure why you wanted to make a new Set
// doing some processing on o
}

Where does t2 get set from? It looks like it's always null to me, and therefor the if statement never gets executed. Put a break point there and see what happens.

We don't use iterators in Java anymore:
We use 'in'
ArrayList<String> stringList = new ArrayList<String>();
// initialize it with code (not shown)
for (String s: stringList) {
System.out.println("the current element is:" + s);
}

You are not iterating correctly.
you need to do
HashSet set = ...
Iterator _i = set.iterator();
while(_i.hasNext()) {
Object o = _i.next();
}
start there.
Also, as to your question
o1 = o2
Nothing happens to memory. In java, everything is either a primitive or a class. All classes reside in the heap, so o1 = o2 just copies the pointer to o2 over to the variable o1. If o2 is a primitive, it copies the value (rather than a pointer) into o1

Related

ConcurrentModificationException When removing element using list iterator java

I have an issue removing the 1st and 2nd element of my list even by using the iterator.
I have read the following threads but can't fix my issue (those were the most relevant but I checked other material as well):
ConcurrentModificationException when trying remove element from list
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
So my code looks like this:
List<List<String>> list = cnf.read();
List<List<String>> nlist = new ArrayList<>();
for (List<String> l : list) {
if (l.size() <= 3) {
nlist.add(l);
} else {
int size = l.size();
while (size > 3) {
List<String> three = l.subList(0, 2);
three.add("Y" + (count++));
//Iterator itr = l.iterator();
ListIterator itr = l.listIterator();
int v = 0;
while (itr.hasNext()) {
itr.next();
if (v == 0 || v == 1) {
itr.remove();
v++;
}
}
l.add(0, "Y" + (count++));
size--;
nlist.add(three);
}
nlist.add(l);
}
}
for (List<String> l : nlist) {
System.out.println(l.toString());
System.out.println(l.size());
}
I get a ConcurrentModificationException at the print statement here :
System.out.println(l.toString());
I tried using iterators for my 2 for loops as well but It doesn't seem to make a difference!
I am new to posting questions so let me know If I am doing it right!
Thank you.
After A long debugging, here is the solution.
The sublist function passes by reference and not by value, a sublist created by ArrayList.subList call keeps a reference to the original list and accesses its elementData array directly.
For this reason, when adding an element to the "three" list, we alter the state of the original list. this happens here:
three.add("Y" + (count++));
A way of fixing it for this specific case is to create and initialize the "three" list the following way:
String one = l.get(0);
String two = l.get(1);
List<String> three = new ArrayList<>();
three.add(one);
three.add(two);
three.add("Y" + (count));
This allows us to manipulate our lists without getting Concurrency Exceptions (ConcurrentModificationException). However, if you are manipulating big lists, I would suggest you use another less hardcoded method for list creation.
I will mark this thread as answered and hope it helps people.

Caused by: java.util.ConcurrentModificationException

I don't understand why this is happening. I was doing a bit of research on other questions and I found out that you can't modify an collection while using a for loop. However, I am using an Iterator, why is it not working?
int counter = 0;
int otherCounter = 0;
ArrayList<Character> chars = new ArrayList<Character>();
Iterator<Character> i = chars.iterator();
for (char s : e.getMessage().toCharArray()) {
chars.add(s);
}
while (i.hasNext()) {
char s = i.next();
if (chars.get(otherCounter + 1) == s) {
counter++;
} else {
counter = 0;
}
if (counter >= 2) {
i.remove();
}
otherCounter++;
}
I am getting an error on this line for some reason:
char s = i.next();
You're adding to the collection after creating the iterator.
This throws that exception.
You need to create the iterator after you finish modifying the collection.
This is because an "enhanced for loop" as you are using it creates an Iterator behind the scenes.
In fact, when you write:
for (X x: whatever) {
// do something with x
}
the "real", generated code goes something like:
Iterator<X> iterator = whatever.iterator();
while (iterator.hasNext()) {
X x = iterator.next();
// do something with x
}
And this is true if whatever implements Iterable<X> (which List does; in fact, any Collection does)
In your example, you create a List<Character>, create a first Iterator<Character> over it, and your for loop creates another Iterator<Character>, over the same list.
Note that you created the first before you modified your List... Hence the result. The first Iterator, which you reuse only afterwards, will detect that in the meanwhile, its underlying list has been modified: boom.

Next element using for loops java

Very rudimentary question but I have a loop e.g.
List<ObjectList> = //set of values inside.
for(Object data : ObjectList){
// how to access next element?
// current element is accesed by 'data'. I could get the index position and then increment but is there a easier way?
}
How would you get the next element/previous? I know there are iterators i can use and so on but i want to know a neat way to do it in a for loop.
You can but don't do it as the time complexity of the loop will
increase. Just use a normal loop with an int i looping variable.
If you still want to do it you can find the index this way:
int index = lst.indexOf(data);
Then index+1 is the index of the next element.
And index-1 is the index of the previous element.
Make two methods for next and pervious and pass list and element.
public static <T> T nextElement(List<T> list,T element){
int nextIndex=list.indexOf(element)+1;
return list.size()<nextIndexlist?null:list.get(nextIndex);
}
public static <T> T previousElement(List<T> list,T element){
int previousIndex=list.indexOf(element)-1;
return list.size()>previousIndexlist?null:list.get(previousIndex);
}
1)First way
for(ObjectList data : objectList){
ObjectList previousElement=previousElement(objectList,data);
ObjectList nextElement=nextElement(objectList,data);
}
2) Second way
for(int i=0;i<=objectList.size();i++){
ObjectList previousElement=objectList.size>i-1?null:objectList.get(i-1);
ObjectList nextElement=objectList.size<i+1?null:objectList.get(i+1);
}
3) Third way using iterator
Actually, your for-each isn't iterating a List. This,
List<ObjectList> = //set of values inside.
for(Object data : ObjectList){
}
Should look something like,
List<ObjectList> al = new ArrayList<>();
for(ObjectList data : al){ // <-- like so.
}
But that won't find any data until you populate the List.
Using a "normal" for-loop, this might be, what you are looking for:
List<Object> objectList = new ArrayList<>();
// add some data
for (int i = 0; i < objectList.size(); i++) {
System.out.println((i > 0) ? "previous Object: " + objectList.get(i - 1) : "No previous object, current is the first one.");
System.out.println("Current Object: " + objectList.get(i));
System.out.println((i < objectList.size()) ? "Next Object: " + objectList.get(i + 1) : "No next object, current is the last one.");
}
Key aspect is, that you have to use your loop variable (i in this case) to access your actual elements. i + 1 gives you the next element and i - 1 the previous.
I think what you is an iterator, its used like this:
List<ObjectList> list= //set of values inside.
Iterator<ObjectList> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
System.out.println(iterator.previous());
iterator.next()
}
It allows you to access the next and previous objects.
ListIterator:
There is the ListIterator which can a bit of stepping back and forth.
Mind in the code below previousIndex() yields -1 at the start.
for (ListIterator<Object> iter = objectList.listIterator(); iter.hasNext(); ) {
Object object = iter.next();
Object previous = objectList.get(iter.previousIndex()); // Might fail
Object next = objectList.get(iter.nextIndex()); // Might fail
if (iter.hasPrevious()) ... iter.previous();
}

How to print content in Collection in Java

Good day All,
Normally, I will print all the content in List by look the list.size() and assign it to an object and print the object value. The following is my example code:
List ccUserList = new ArrayList(); // Here I declare a List
Collection ccGroupCol = new ArrayList(); // Here I declare a collection
CCuserBO bo = null;
ccUserList = getSummaryList();
for(int i = 0, i < ccUserList.size() , i++){
bo = ( CCUserBO ) ccUserList.get(i);
System.out.println(bo.userName);
}
I would like to ask about the way to print content in Collection.
Since Collection no have .get() function.
The following in the code that I try in Collection:
CCuserBO newBo = null;
ccGroupCol = getSummaryList();
Iterator iterator = ccGroupCol.iterator();
while ( iterator.hasNext()){
newBo = iterator.next(); //error here, Type mismatch: cannot convert from Object to //Object[]
System.out.println("....");
}
If you simply want to print all elements of a Collection just sysout Collection directly it will provide you the following form in output: [element1, element2, ....] because toString() method is overrided and implemented to provide such output for all Collection classses.
By using Iterator you can get the element one by one:
Iterator iterator = ccGroupCol.iterator();
while ( iterator.hasNext()){
newBo = (**type cast here to particular newBo object type**)iterator.next();
System.out.println(newBo);//here whatever you implemented in toString() method
// in newBo type class(if you did so), you will get that type of output, if you do not override
//toString() to provide your implementation,you will get default implementation in
//which it will show <the object class>#<its hash code>
}
Note: the return type of iterator.next() is Object type, so you must type cast it to avoid incompatible type exception. Or use Generics.
I found the solution. Here is the example code:
CCGroupBO newBo;
for(int i = 0 ; i < ccGroupCol.size() ; i++){
newBo = ( CCGroupBO ) ccGroupCol.toArray()[i];
System.out.println(newBo.getGroupName());
}
Thanks for all your help.
You can use the for loop to iterate the collection.
Collection collection= new ArrayList();
for (Object obj : collection) {
//Here you can type cast the obj then you can print.
}
As statet in comment, a faster solution for your own answer:
Collection<CCGroupBO> ccGroupCol = new ArrayList<CCGroupBO>()
…
CCGroupBO[] boArray = ccGroupCol.toArray();
for(CCGroupBO newBo : boArray){
System.out.println(newBo.getGroupName());
}
or even more direct:
Collection<CCGroupBO> ccGroupCol = new ArrayList<CCGroupBO>()
…
for(CCGroupBO newBo : ccGroupCol){
System.out.println(newBo.getGroupName());
}
depending on other circumstances there is even a nicer method:
class CCGroupBO {
…
public String toString() {
return getGroupName();
}
}
…
Collection<CCGroupBO> ccGroupCol = new ArrayList<CCGroupBO>()
…
System.out.println(ccGroupCol);

Getting most recent objects in a list

How can i get the most recent objects in a List?
I have tried
int i = 5;
while(i > 0) {
Object o = list.get(list.size() - i);
i--;
}
but to no avail, i could be doing it wrong, but if i am i am unware how to fix my mistake :/
(The problem is it is still giving me the entire list)
You could just reverse the list then iterate over it:
// Your original list
List<Object> list = new ArrayList<Object>(); // Populated elsewhere
// Make a copy, so you don't corrupt the original list
List<Object> reverseList = new ArrayList<Object>(list);
// Reverse the order of its elements
Collections.reverse(reverseList);
// Now iteration will be in "latest added first" order - ie LIFO
for (Object o : reverseList) {
// Do something with o
}
I think that you're expecting your code to change the original list, but this is a wrong assumption since the code simply gets an object held by the list and doesn't remove it. Then you discard the object held by o, so there is no way to test if your method is working or not. To solve this, you've got to save the stuff produced from your method to test if it works or not.
int i = 5;
List savedJunk = new ArrayList();
while(i > 0) {
Object o = list.get(list.size() - i);
savedJunk.add(o);
i--;
}
for (Object foo : savedJunk) {
System.out.println(foo);
}
It's a good question and you pretty much had the right answer. The central idea is that items in a list appear in the order in which you added them, so to get the most recent item you need to go through the list in reverse. Here is one way to do that with a for loop.
ArrayList<String> myList = new ArrayList<String>();
myList.add("one");
myList.add("two");
myList.add("three");
myList.add("four");
for (int index = myList.size() - 1; index >= 0 ; index--) {
System.out.println(myList.get(index));
}
The output of the above code is:
four
three
two
one

Categories