Get specific class objects from HashSet in Java - java

I have a public Set<ProjectItem> projectItems = new HashSet<ProjectItem>(); which can contains two types of classes (ProjectItem is a abstract super class for both of them). The classes are Deliverable and Task. I want get all objects of the class Deliverable from the Set. Therefore I write this:
public Set<Deliverable> allDeliverables(){
Set<Deliverable> result = new HashSet<Deliverable>();
for(Iterator<ProjectItem> iter = projectItems.iterator(); iter.hasNext(); iter.next()){
if (iter.next().getClass() == Deliverable.class){
Deliverable del = (Deliverable) iter.next();
result.add(del);
}
}
return result;
}
But this makes an exception -
Exception in thread "main" java.lang.ClassCastException: edu.Chryb.ProjectManagement.Task cannot be cast to edu.Chryb.ProjectManagement.Deliverable
in the Line with: Deliverable del = (Deliverable) iter.next();
Is something in the if query wrong?
Thanks for every help.

Your code is a bit out. Try:
for(Iterator<ProjectItem> iter = projectItems.iterator(); iter.hasNext(); iter.next()){
ProjectItem item = iter.next();
if (item.getClass() == Deliverable.class){
result.add((Deliverable)item);
}
}

The problem is the multiple invocations of iter.next() (because it return current element and forwards the cursor to the next element) within the loop.
Within the loop do something as follows first -
for(Iterator<ProjectItem> iter = projectItems.iterator(); iter.hasNext();){
ProjectItem currItem = iter.next();
//...
And then use currItem instead of calling iter.next() multiple times.
Side Note:
for(Iterator<ProjectItem> iter = projectItems.iterator(); iter.hasNext(); iter.next()) {
The call iter.next() doesn't have to do with the mentioned problem but it shouldn't be there also. Because that you will skip actual current element.

You are calling iter.next() twice - once in the check, and once on the retrieval. It appears that you find a Deliverable followed by Task. The check of Deliverable succeeds, but the iterator moves on to Task right after that, so the following invocation of next returns a Task, not a Deliverable.
Change your code as follows:
for(Iterator<ProjectItem> iter = projectItems.iterator(); iter.hasNext(); iter.next()){
ProjectItem next = iter.next();
if (next.getClass() == Deliverable.class){
Deliverable del = (Deliverable) next;
result.add(del);
}
}

Related

Llist of items that have been deleted

I want to display the list of items that i have deleted so far (JAVA). I'm using database as mysql. I'm giving a button in UI on clicking it web service will called and should display the deleted entry. I tried this:
for (Iterator<String> iter = list.listIterator(); iter.hasNext(); ) {
String a = iter.next();
if (...) {
iter.remove();
}
}
You can store all the removed items in a data structure like linked list which is appropriate for appending new items and you don't need to consist memory to it when you define it.
List<String> listOfRemovedItems = new LinkedList<>();
Iterator iterator = originalList.iterator();
while (iterator.hasNext()) {
String s = iterator.next().toString();
if ("meets your condition") {
listOfRemovedItems.add(s);
iterator.remove();
}
}
I added one extra column in table as Flag. Now when user delete it flag is to 1 otherwise it is false.

Adding and getting Comm Ports from RXTX

I am currently working on a project which needs to communicate with a device connected on a commport. I have one function below which searches for serial ports, adds them to a hashmap then returns the hashmap. I noticed a problem where whenever I try to get something from the HashMap, it give a java.lang.nullPointerException Am I trying to get the port from the map incorrectly? Please let me know if I need to post more code.
private Enumeration ports = null;
public HashMap<String, CommPortIdentifier> searchForPorts() {
ports = CommPortIdentifier.getPortIdentifiers();
while (ports.hasMoreElements()) {
CommPortIdentifier curPort = (CommPortIdentifier) ports.nextElement();
if (curPort.getPortType() == CommPortIdentifier.PORT_SERIAL) {
System.out.println("Adding: " + curPort.getName() + "-" + curPort);
portMap.put(curPort.getName(), curPort);
System.out.println(portMap.get(curPort.getName())); //works: prints out gnu.io.CommPortIdentifier#9f116cc
}
}
log.fine("Successfully looked for ports");
Iterator it = portMap.entrySet().iterator();
String s="";
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
s = pair.getKey().toString();
System.out.println(s); //prints out COM24 like it should
it.remove();
}
System.out.println(portMap.get(s)); //Prints out null??
return portMap;
}
Portions of this code are taken from here.
You remove elements in your map using it.remove() as it's stated in the javadoc: Removes from the underlying collection the last element returned by this iterator
To access next element using an iterator you just need to use it.next() (assuming there is remaining elements).
Another solution is to use a foreach loop like this:
for(Map.Entry pair : portMap.entrySet()){
s = pair.getKey().toString();
System.out.println(s);
}

Java iterator.hasNext() is always true

I have a little problem with the code as seen below. The iterator().hasNext() will never turn into false because the next() function always returns the same element. It ends in an infinite loop.
I would like to set the attribute UserLock in every element in the collection (returned from GetElements()).
If the type of the element is "Package", I will lock all elements under the package with a recursive call of the lockAllElements function.
private void lockAllElements(String internalGUID) {
Element tempElem = null;
while((repo.GetPackageByGuid(internalGUID).GetElements().iterator().hasNext()) == true) {
tempElem = repo.GetPackageByGuid(internalGUID).GetElements().iterator().next();
if(tempElem.GetType().equals("Package")) {
this.lockAllElements(tempElem.GetElementGUID());
}
tempElem.ApplyUserLock();
}
}
It is always true because you get a new Iterator instance in each iteration of your loop. You should get a single Iterator instance and use that instance throughout the loop.
Change
while((repo.GetPackageByGuid(internalGUID).GetElements().iterator().hasNext()) == true) {
tempElem = repo.GetPackageByGuid(internalGUID).GetElements().iterator().next();
...
to
Iterator<Element> iter = repo.GetPackageByGuid(internalGUID).GetElements().iterator();
while(iter.hasNext()) {
tempElem = iter.next();
...
Following on from #Eran's answer... I sometimes prefer a for loop:
for (Iterator<Element> iter = repo.GetPackageByGuid(internalGUID).GetElements().iterator(); iter.hasNext(); ) {
tempElem = iter.next();
}

How to remove element from ArrayList?

I have added data into ArrayList and now want to update that list be deleting some element from it.
I have element something like 1,2,3,4 in ArrayList of type CartEntry.
Code :
ArrayList<CartEntry> items = new ArrayList<CartEntry>();
public void remove(int pId)
{
System.out.println(items.size());
for(CartEntry ce : items)
{
if(ce.getpId() == pId)
{
items.remove(ce);
//System.out.println(items.get(1));
}
}
items.add(new CartEntry(pId));
}
CartEntry Code :
public long getpId() {
return pId;
}
Constructor :
public CartEntry(long pId) {
super();
this.pId = pId;
}
when I am trying this code it gives me an error:
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
Here pId is the argument that specify that item should be deleted from items.
Suppose I want to delete item that have 2 data then what will I have to do ?
You are facing ConcurrentModificationException because you are doing two operations on the same list at a time. i.e looping and removing same time.
Inorder to avoid this situation use Iterator,which guarantees you to remove the element from list safely .
A simple example looks like
Iterator<CartEntry> it = list.iterator();
while (it.hasNext()) {
if (it.next().getpId() == pId) {
it.remove();
break;
}
}
There are at least two problems with your code:
you call remove on the collection you iterate over, that will cause a ConcurrentModificationException if you continue iterating after the remove.
There are two ways to fix this:
stop iterating after you found the object you want to remove (just add a break or a return) or
switch from the enhanced for-loop to using an Iterator and its remove method.
you add an element in your remove method, that's probably not what you want.
So I'd use this code (this assumes that there is only ever one CartEntry with a given id in the list):
public void remove(int pId)
{
for(CartEntry ce : items)
{
if(ce.getpId() == pId)
{
items.remove(ce);
return;
}
}
}
If the assumption with the unique id is not correct, then you'll need to use the Iterator approach:
public void remove(int pId)
{
Iterator<CartEntry> it = items.iterator();
while(it.hasNext())
{
CartEntry ce = it.next();
if(ce.getpId() == pId)
{
it.remove();
}
}
}
you have created an Arraylist of type carEntry. So you need to create an Iterator of type CarEntry
Iterator<CarEntry> it = items.iterator();
while(it.hasNext())
{
if(it.next().getPId == PId)
it.remove();
}
Implement .equals in CartEntry and then use ArrayList.remove(CartEntry) or loop through your array list, find the item with some condition, mark the index, and call ArrayList.remove(index) -- AFTER the loop
Try,
public void remove(int pId){
Iterator<CartEntry> it = items.iterator();
while(it.hasNext()) {
CartEntry entry = it.next();
if (entry.getpId() == pId) {
it.remove();
}
}
}
The enhanced-for(or for each) loop for iterating over an Expression which is a subtype of Iterable<E> or raw Iterable, basically equivalent to the following form:
for (I #i = Expression.iterator(); #i.hasNext(); ) {
VariableIdentifiers_opt TargetType Identifier = (TargetType) #i.next();
Statement
}
This is clearly stated in jls 14.14.2. The enhanced for statement section.
For your context the Expression is an ArrayList. the iterators returned by ArrayList's iterator method is fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.
use an Iterator instead and use it's own remove() method:
Iterator<E>iterator = list.iterator();
while(iterator.hasNext())
if(iterator.next().equals(E))
iterator.remove();

How can I make an iterator that never ends?

I was just wondering what the easiest way to iterate over a set indefinitely, i.e. when it reaches the end it next(); calls the first object. I'm assuming that this is not an already predefined function in Java, so just looking for the easiest way to implement this in Java.
There's a method in the excellent Google Collections library which does this:
Set<String> names = ...;
Iterable<String> infinite = Iterables.cycle(names);
(I can't recommend the Google Collections library strongly enough. It rocks very hard. I'm biased as I work for Google, but I think pretty much every Googler writing Java would tell you how useful the collections are.)
Iterator it = mylist.iterator();
while (it.hasNext())
{
MyType t = (MyType)it.next();
// do something
if (!it.hasNext())
it = mylist.iterator();
}
Try EndlessIterator from Cactoos:
Iterator<String> names = new EndlessIterator<>("John");
It will always return "John" and will never end.
Also, check EndlessIterable, which implements Iterable and does the same.
If you're making the iterator, in the next method you can have an if condition that checks if there's another object in the list. If there is, then you return that object, if there isn't then you go back to the start of the list and return that object.
This is what I can think of...
iterator = set.getIterator
//other code
if (iterator.hasNext())
//do code here
else
iterator = set.getIterator();
How about ?
List<String> list = // ArraysList
Interator<String> it = null;
while(true) {
it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
If you don't want to use Guava but still want a reusable solution:
public static class CyclicIterator<E, C extends Collection<E>> implements Iterator<E> {
final private C mElements;
private Iterator<E> mIterator;
public CyclicIterator(C elements) {
mElements = elements;
mIterator = elements.iterator();
}
#Override
public boolean hasNext() {
if (! mIterator.hasNext()) {
mIterator = mElements.iterator();
}
return mIterator.hasNext();
}
#Override
public E next() {
if (! mIterator.hasNext()) {
mIterator = mElements.iterator();
}
return mIterator.next();
}
}
Note: this doesn't support the remove() method but it could easily be added if needed. Also it's not thread safe.
I think what you want never help You can do anything with your iterator that's easy but you must be carefull with any new thing you add im not used with this style but this is what you want though :
if (! It.hasNext() )
{
while ( It.hasPrevious() )
{
It = It.Previous();
}
} else {
It = It.Next();
}
This way is nothing if your really interested you should instead make next pointer of the last to the first always when pushing a new list.
std jdk:
Iterable<String> infinite = Stream.generate(names.stream()).flatMap(e -> e).iterator()

Categories

Resources