Reputation: 189
I have an object class which is contains a list of itself... Something like this:
public class SearchItemType implements Serializable {
protected List<SearchItemType> childItem;
}
The childItem also can conatain list of child items. My question is, can I iterate over childItems in all levels?
Right now my code looks like this:
public SearchItemType getElementByOpenedRowID(SearchItemType gridResult, String selectedRowId, Boolean found) {
SearchItemType element = new SearchItemType();
if (gridResult.getId().equals(selectedRowId)) {
element = gridResult;
found = true;
}
for (SearchItemType child : gridResult.getChildItem()) {
if (child.getId().equals(selectedRowId)) {
element = child;
found = true;
break;
}
}
if (!found) {
for (SearchItemType child : gridResult.getChildItem()) {
element = getElementByOpenedRowID(child, selectedRowId, found);
checkChildID(child, selectedRowId);
if (element != null) break;
}
}
return element;
}
Many thanks.
Upvotes: 0
Views: 3597
Reputation: 143
I played around by creating an iterator.
See this:
public class SearchItemType {
protected List<SearchItemType> childItem = new ArrayList();
protected String id;
public SearchItemType(String id) {
this.id = id;
}
public static void main(String[] args) {
SearchItemType one = new SearchItemType("1");
SearchItemType one_one = new SearchItemType("1.1");
SearchItemType one_two = new SearchItemType("1.2");
SearchItemType one_three = new SearchItemType("1.3");
SearchItemType one_four = new SearchItemType("1.4");
SearchItemType one_two_one = new SearchItemType("1.2.1");
SearchItemType one_two_two = new SearchItemType("1.2.2");
SearchItemType one_two_three = new SearchItemType("1.2.3");
SearchItemType one_three_one = new SearchItemType("1.3.1");
SearchItemType one_three_two = new SearchItemType("1.3.2");
SearchItemType one_three_three = new SearchItemType("1.3.3");
SearchItemType one_three_two_one = new SearchItemType("1.3.2.1");
SearchItemType one_three_two_two = new SearchItemType("1.3.2.2");
one.childItem.add(one_one);
one.childItem.add(one_two);
one.childItem.add(one_three);
one.childItem.add(one_four);
one_two.childItem.add(one_two_one);
one_two.childItem.add(one_two_two);
one_two.childItem.add(one_two_three);
one_three.childItem.add(one_three_one);
one_three.childItem.add(one_three_two);
one_three.childItem.add(one_three_three);
one_three_two.childItem.add(one_three_two_one);
one_three_two.childItem.add(one_three_two_two);
Iterator<SearchItemType> itr = one.getItemTypeIterator();
while (itr.hasNext())
System.out.println(itr.next().id);
}
public Iterator<SearchItemType> getItemTypeIterator() {
return new Iterator<SearchItemType>() {
ArrayList<SearchItemType> parents = new ArrayList();
SearchItemType next = null;
boolean avoidChildren = false, nextSearched = false;
public boolean hasNext() {
if (!nextSearched)
searchNext();
nextSearched = true;
return next != null;
}
public SearchItemType next() {
if (!nextSearched)
searchNext();
nextSearched = false;
return next;
}
private void searchNext() {
if (next == null) {
next = SearchItemType.this;
return;
}
if (!avoidChildren) {
if (next.childItem.size() > 0) {
parents.add(next);
next = next.childItem.get(0);
} else {
avoidChildren = true;
}
}
if (avoidChildren) {
while (parents.size() > 0) {
SearchItemType lastParent = parents.get(parents.size() - 1);
int i = lastParent.childItem.indexOf(next);
if (i < lastParent.childItem.size() - 1) {
next = lastParent.childItem.get(i + 1);
avoidChildren = false;
return;
} else {
next = lastParent;
parents.remove(parents.size() - 1);
}
}
next = null;
}
}
};
}
}
The result is:
1
1.1
1.2
1.2.1
1.2.2
1.2.3
1.3
1.3.1
1.3.2
1.3.2.1
1.3.2.2
1.3.3
1.4
Upvotes: 0
Reputation: 2342
There is one error: at the start of the method, you set SearchItemType element = new SearchItemType();
but then check for null
when you recurse. element
will never be null. You can fix this by setting it to null
at the start, but I have some suggestions about your code:
found
flag, just return the object as soon as you find it. At the end of the method return null
. This will be much clearer.found
as a parameter? If you pass it true
, then there is no point in having it, so if you really need it, just instantiate it in the method.gridResult
is not null. You could remedy this by making getElementByOpenedRowID
a method on SearchItemType
, meaning that gridResult
does not need to be passed.Applying these changes will result in:
public SearchItemType getElementByOpenedRowID(SearchItemType gridResult, String selectedRowId) {
// stop at null
if (gridResult == null) {
return null;
}
if (gridResult.getId().equals(selectedRowId)) {
return gridResult; // return once found
}
// check all of the children
for (SearchItemType child : gridResult.getChildItem()) {
// do the search again for every child
SearchItemType result = getElementByOpenedRowID(child, selectedRowId);
if (result != null) {
// return once found and sent it all the way to the top
return result;
}
}
return null;
}
Upvotes: 1
Reputation: 127
You want to iterate through the children recursively as so:
public SearchItemType getElementByOpenedRowID(SearchItemType gridResult, String selectedRowId) {
SearchItemType element = null;
if (gridResult == null) return null;
else if (gridResult.getId().equals(selectedRowId)) return gridResult;
else {
for (SearchItemType child : gridResult.getChildItem()) {
element = getElementByOpenedRowID(child, selectedRowId);
if (element != null) break;
}
}
return element;
}
Upvotes: 0
Reputation: 230
Yes you can iterate on childItem
object at any level as long as childItem
is not null and object inside it has non-null values.
In Data structure implementation of LinkedList every node in the LinkedList has Data
fields link to other nodes (In case of Java it's reference to other nodes).
It's also called as self referencing objects that means object pointing to object of similar type.
As long as you have non-null values in the list you can iterate at any level.
Data structures in Java
are implemented in similar manner.
Have look at Node class
in this code snippet:
Linked List implementation using self referencing pointers
Upvotes: 0
Reputation: 4039
You can do this with recursion:
public void iterate(SearchItemType type) {
// Do something with type
for (SearchItemType child in type.childItem) {
iterate(child);
}
}
Upvotes: 0