繁体   English   中英

Java-如何获取交错的迭代器/集合

[英]Java - how to obtain an interleaved iterator/collection

假设我们异步接收来自3个生产者的字符串。 一旦接收到一定数量的这些对象,我想以交错的方式遍历它们,也就是说,如果接收到以下字符串:

"a1" received from A,
"a2" received from A,
"c1" received from C,
"a3" received from A,
"b1" received from B,
"b2" received from B,

我希望“交错式”迭代器返回字符串,就好像我们在遍历以下列表一样:

List<String> interleavedList = {"a1", "b1", "c1", "a2", "c2", "a3"},

到目前为止,我已经为每个生产者创建了一个List<String> ,然后通过使用3个列表迭代器(使用List<Iterator<String>> )对所有字符串进行“迭代”。 这可以正常工作,但是我认为有一种更简单的方法……也许是通过在接收字符串的同时直接构造交错列表? 但我看不到要使用哪个Collection或哪个Comparator ...

请注意,我不太想为每个生产者创建一个列表,然后将3个列表合并到第4个交错列表中,因为这可能不省时。

似乎您希望对列表进行排序,其中数字确定排序的第一位,第二个字母。 Java没有排序列表,因为列表的性质是它们没有排序。 但是,您可以使用带有自定义比较器的排序集:

SortedSet<String> sortedset = new TreeSet<String>(
        new Comparator<String>() {
            @Override
            public int compare(String e1, String e2) {
                int num1 = Integer.parseInt(e1.replaceAll("[^\\d.]", ""));
                int num2 = Integer.parseInt(e2.replaceAll("[^\\d.]", ""));
                if (num1 > num2) {
                    return 1;
                }
                else if (num1 < num2) {
                    return -1;
                }
                else {
                    String let1 = e1.replaceAll("[0-9]", "");
                    String let2 = e2.replaceAll("[0-9]", "");
                    return let1.compareTo(let2);
                }
            }
        });

遍历此集合时,您将获得问题中描述的顺序。

一种选择是根据对象到达的特定于生产者的索引将所有对象转储到PriorityBlockingQueue中:

class Message {
   String data;
   long index;
}

PriorityBlockingQueue<Message> queue = new PriorityBlockingQueue<Message>(
  10,
  Comparator.comparing(m -> m.index)
); 

List<String> batch = new ArrayList<>(BATCH_SIZE);
for (;;) {
   for (int i = 0; i < BATCH_SIZE; i++) {
      batch.add(queue.take().data);
   }
   handleBatch(batch);
   batch.clear();
}

注意,这里假设队列是无限的。 如果队列不是无限的,则必须添加一些逻辑来处理最后一批。

您可以使用自定义Comparator将字符串添加到PriorityQueue<String> 在这种情况下,您的元素将在添加时自动排序。 这是一个有用的例子

我最近遇到了类似的问题,这是我想出的(只是依次从每个迭代器中取出,直到所有迭代器都耗尽,不进行排序):

import java.util.Collection;
import java.util.Iterator;

public class InterleavedIterator<T> implements Iterator<T> {

  static class Node<K> {
    Node<K> next;
    Node<K> prev;
    final K value;

    Node(K value) {
      this.value = value;
    }

    public void setNext(Node<K> next) {
      this.next = next;
    }

    public void setPrev(Node<K> prev) {
      this.prev = prev;
    }
  }

  private Node<Iterator<T>> node;

  public InterleavedIterator(Collection<Iterator<T>> iterators) {
    Node<Iterator<T>> prev = null;
    for (Iterator<T> iterator : iterators) {
      if (!iterator.hasNext()) {
        continue;
      }
      Node<Iterator<T>> current = new Node<>(iterator);
      if (prev != null) {
        prev.setNext(current);
        current.setPrev(prev);
      } else {
        node = current;
      }
      prev = current;
    }
    if (prev != null) {
      prev.setNext(node);
      node.setPrev(prev);
    }
  }

  @Override
  public boolean hasNext() {
    return node.value.hasNext();
  }

  @Override
  public T next() {
    T res = node.value.next();
    updateNode();
    return res;
  }

  private void updateNode() {
    Node<Iterator<T>> nextNode = node.next;
    if (node.value.hasNext()) {
      node = nextNode;
    } else if (node != nextNode) {
      node.prev.next = nextNode;
      nextNode.prev = node.prev;
      node = nextNode;
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM