Сворачивание последовательного потока в Java

Я привык к программированию в Scala, но мне нужно написать немного Java, и я пытаюсь выполнить эквивалент следующего фрагмента Scala:

 trait Options[K, V] {
  def add(key: K , value: V): Options[K, V]
}

val options: Options[T, U] = ???
val elems: List[(T, U)] = ???
elems.foldLeft(options) {
  case (opts, (key, value)) => opts.add(key, value)
}

То есть я складываю элементы в elems внутри options, создавая новый экземпляр на каждом шаге.

Я пытался использовать Stream#reduce :

interface Options<K, V> {
  Options<K, V> add(K key, V value);
}

Options<K, V> options = ???
Stream<Tuple2<K, V>> elems = ??? // This is Reactor's Tuple2
elems.reduce(options, (opts, opt) -> opts.add(opt), ???)

Я не знаю, каким должен быть комбинатор, и мне трудно представить, какие значения будут иметь его аргументы. Насколько я понимаю, combiner будет использоваться для объединения промежуточных значений, полученных параллельно в параллельном потоке. Меня совершенно не волнует параллельная обработка elems в моем случае. Другими словами, я ищу синхронную и последовательную версию Flux#reduce .

У меня нет контроля над API Options. elems не обязательно должен быть Stream .

4 голоса | спросил Martin 28 Jpm1000000pmMon, 28 Jan 2019 18:27:24 +030019 2019, 18:27:24

1 ответ


0
Невозможно написать сумматор с предоставленным вами интерфейсом.Проблема в том, что комбинатору нужен способ объединить два ---- +: = 0 =: + ----, но сделать это невозможно.Единственное, что каждый может сделать с экземпляром ---- +: = 1 =: + ----, это добавить к нему одну пару.Я не могу получить какую-либо информацию из этого.По-видимому, он не может сделать что-нибудь очень полезное.Возможно, эта проблема связана с тем, что в Java нет признаков, и интерфейсы Java не являются подходящей заменой признаков.Идиоматический способ написания Java-кода - это просто стандартный for-loop:Если вы можете справиться с тем фактом, что вы никогда не сможете использовать параллельный поток, вы можете воспользоваться тем фактом, что последовательный поток никогда не будет использовать объединитель.Таким образом, вы можете написать ---- +: = 3 =: + ----, который определяет комбинатор, который просто сгенерирует исключение.Если вы действительно хотите использовать ---- +: = 5 =: + ---- , вам нужно изменить интерфейс, чтобы предоставить некоторую информацию о парах ключ-значение, которые он содержит, или предоставить средство для добавленияболее одной пары ключ-значение одновременно.Например:Я сомневаюсь, что это то, что вы хотели услышать, но Scala и Java - это разные языки.Вы не должны ожидать, что все будет иметь точную параллель.Если бы это было так, то не было бы оснований для существования обоих языков.
ответил Michael 28 Jpm1000000pmMon, 28 Jan 2019 18:54:39 +030019 2019, 18:54:39

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132