All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.metamx.common.guava.nary.SortedMergeIterator Maven / Gradle / Ivy

There is a newer version: 1.3.8
Show newest version
/*
 * Copyright 2011,2012 Metamarkets Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.metamx.common.guava.nary;

import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;

import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * A SortedMergeIterator is an Iterator that combines two other Iterators into one.
 *
 * It assumes that the two Iterators are in sorted order and walks through them, passing their values to the
 * BinaryFn in sorted order.  If a value appears in one Iterator and not in the other, e.g. if the lhs has a value "1"
 * and the rhs does not, the BinaryFn will be called with "1" for first argument and null for the second argument.
 * Thus, the BinaryFn implementation *must* be aware of nulls.
 *
 */
public class SortedMergeIterator implements Iterator
{
  public static  SortedMergeIterator create(
      Iterator lhs,
      Iterator rhs,
      Comparator comparator,
      BinaryFn fn
  )
  {
    return new SortedMergeIterator<>(lhs, rhs, comparator, fn);
  }

  private final PeekingIterator lhs;
  private final PeekingIterator rhs;
  private final Comparator comparator;
  private final BinaryFn fn;

  public SortedMergeIterator(
      Iterator lhs,
      Iterator rhs,
      Comparator comparator,
      BinaryFn fn
  )
  {
    this.lhs = Iterators.peekingIterator(lhs);
    this.rhs = Iterators.peekingIterator(rhs);
    this.comparator = comparator;
    this.fn = fn;
  }

  @Override
  public boolean hasNext()
  {
    return lhs.hasNext() || rhs.hasNext();
  }

  @Override
  public OutType next()
  {
    if (! hasNext()) {
      throw new NoSuchElementException();
    }

    if (! lhs.hasNext()) {
      return fn.apply(null, rhs.next());
    }
    if (! rhs.hasNext()) {
      return fn.apply(lhs.next(), null);
    }

    int compared = comparator.compare(lhs.peek(), rhs.peek());

    if (compared < 0) {
      return fn.apply(lhs.next(), null);
    }
    if (compared == 0) {
      return fn.apply(lhs.next(), rhs.next());
    }

    return fn.apply(null, rhs.next());
  }

  @Override
  public void remove()
  {
    throw new UnsupportedOperationException();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy