开发者

Java->Scala Remove Iterator<T>-Element from a JavaConversions-wrapped Iterable

I have to translate the following code from Java to Scala:

EDIT: added if-statements in the source (forgot them in first version)

for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) 
{
  if (someCondition) {
    Except开发者_如何学编程ionQueuedEvent event = i.next();
    try {
      //do something
    } finally {
      i.remove();
    }
  }
}

I'm using the JavaConversions library to wrap the Iterable. But as i'm not using the original Iterator, i don't know how to remove the current element correctly from the collection the same way as i did in Java:

import scala.collection.JavaConversions._
(...)
for (val event <- events) {
  if (someCondition) {
    try {
      // do something
    } finally {
      // how can i remove the current event from events?
      // the underlying type of events is java.lang.Iterable[javax.faces.event.ExceptionQueuedEvent]
    } 
  }
}

Can someone help me? I guess it's easy, but i'm still kinda new to Scala and don't understand what's going on when Scala wraps something of Java.


When you use JavaConversions to wrap Java collections, you just get an object that adapts the Java collection to the appropriate Scala trait (interface). In Java, you might see the same thing (for example, you could imagine a adapter class that implements the Iterator interface and wraps an Enumeration.) The only difference is that in Scala you can add the 'implicit' modifier to a declaration to tell the compiler to automatically insert calls to that method if it will make the code compile.

As for your specific use case, Iterators in Scala intentionally omit the remove() method for a number of reasons. The conversion from scala.collection.Iterator to java.util.Iterator promises to unwrap a j.u.Iterator if possible, so I suppose you could rely on that to access the remove() method. However, if you are iterating over the entire collection and removing everything, why not just do your work in a foreach loop and then clear the collection or replace it with an empty one after you finish?


Does this suggest how do accomplish what you want?

scala> val l1 = List("How", "do", "I", "love", "you")
l1: List[java.lang.String] = List(How, do, I, love, you)

scala> val evens = for ( w <- l1; if w.length % 2 == 0 ) yield { printf("even: %s%n", w); w }
even: do
even: love
evens: List[java.lang.String] = List(do, love)

Basically, you get your Scala Iterable or Iterator using the appropriate implicit conversion from JavaConversions, use a for comprehension that includes the condition on which elements you want to process and collect the results. Use exception handling as necessary.


Thanks for all the help. So i had to do without using JavaConversions. But it still looks nice&scalafied ;)**

This is my final code, which seems to work:

val eventsIterator = events.iterator    
for (eventsIterator.hasNext) {
  if (someCondition) {
    try {
      // do something
    } finally {
      eventsIterator.remove
    } 
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜