Java-> Scala Удалить итератор <T>-элемент из итерируемого в JavaConversions - PullRequest
2 голосов
/ 05 июня 2010

Я должен перевести следующий код с Java на Scala:

EDIT: добавлены операторы if в исходном коде (в первой версии они были забыты)

for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) 
{
  if (someCondition) {
    ExceptionQueuedEvent event = i.next();
    try {
      //do something
    } finally {
      i.remove();
    }
  }
}

Я использую библиотеку JavaConversions, чтобы обернуть Iterable. Но так как я не использую оригинальный Iterator, я не знаю, как правильно удалить текущий элемент из коллекции так же, как я делал в 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]
    } 
  }
}

Может кто-нибудь мне помочь? Думаю, это легко, но я все еще новичок в Scala и не понимаю, что происходит, когда Scala оборачивает что-то из Java.

Ответы [ 3 ]

1 голос
/ 05 июня 2010

Когда вы используете JavaConversions для переноса коллекций Java, вы просто получаете объект, который адаптирует коллекцию Java к соответствующей характеристике (интерфейсу) Scala. В Java вы можете увидеть то же самое (например, вы можете представить класс адаптера, который реализует интерфейс Iterator и оборачивает перечисление.) Единственное отличие состоит в том, что в Scala вы можете добавить модификатор 'implicit' в объявление, чтобы сообщить компилятор автоматически вставляет вызовы этого метода, если он заставит код скомпилироваться.

Что касается вашего конкретного случая использования, итераторы в Scala намеренно опускают метод remove () по ряду причин. Преобразование из scala.collection.Iterator в java.util.Iterator обещает развернуть j.u.Iterator, если это возможно, поэтому я полагаю, что вы можете полагаться на это для доступа к методу remove (). Однако если вы перебираете всю коллекцию и удаляете все, почему бы просто не выполнить свою работу в цикле foreach, а затем очистить коллекцию или заменить ее пустой после завершения?

0 голосов
/ 17 июня 2010

Спасибо за помощь. Так что мне пришлось обойтись без использования JavaConversions. Но это все еще выглядит красиво и скалясно;) **

Это мой последний код, который, кажется, работает:

val eventsIterator = events.iterator    
for (eventsIterator.hasNext) {
  if (someCondition) {
    try {
      // do something
    } finally {
      eventsIterator.remove
    } 
  }
}
0 голосов
/ 05 июня 2010

Это говорит о том, как добиться того, что вы хотите?

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)

По сути, вы получаете Scala Iterable или Iterator, используя соответствующее неявное преобразование из JavaConversions, используете понимание for, которое включает условие, на каких элементах вы хотите обрабатывать и собирать результаты. При необходимости используйте обработку исключений.

...