编程 - Java - 将合并算法与操作解除关联

时间:2015-09-05 16:04:49

标签: java merge guava terminology

我的意思是,目前我正在开发两个T类型元素的有序集合之间的合并(只要您提供比较Type的方法,类型就不重要了,例如,在Java中,A {{ 1}}将完成工作。)

我不想要的是必然合并合并过程中涉及的两个数据结构(我不想得到一个整合两个元素的整个新结构)。我想要的是拥有合并过程的某种观察者,以便定义如何处理另一个类中的每个合并元素。例如,想要有这样的东西:

Comparator<T>

如果观察者是观察合并算法的对象并获得行动通知,我的意思是:

merger.merge(leftCollection,rightCollection,theComparator,theObserver).

我已经为排序的集合实现了我的实现,但是...我想分享这种感觉,这里有一个问题,关于以前是否有人想过这个,特别是在Guava Libraries中,有什么是正确的使用的术语。

我认为这是一个正确的问题。对现有解决方案的任何想法都将非常感激。非常感谢你。不要删除我的谢意。 感谢。

2 个答案:

答案 0 :(得分:2)

用于分离数据结构的遍历和数据处理的两种最常用的模式是访问者模式和迭代器模式。这两种模式不仅可以应用于存储器中存在的真实数据结构,还可以应用于虚拟的模式。数据结构(可能不是正确的术语)。例如Java API中的List.subList方法创建列表的一部分视图。因此,它返回的List对象只是对另一个列表数据的一部分的引用。当然,您也可以组合数据结构。例如,您可以使用一个方法,将两个迭代器作为参数,并返回一个新的迭代器,在不使用任何额外内存的情况下合并两个迭代器,因为该合并列表实际上并不存在于RAM中。 如果您使用Scala而不是Java,那么您可以使用许多方法来以多种不同的方式转换迭代器以实现这样的效果。

import java.util.function.Predicate;
import java.util.function.BiPredicate;
import java.util.function.Supplier;
import java.util.function.Consumer;
import java.util.stream.IntStream;
import java.util.NoSuchElementException;

interface MyIterator<T> extends Iterator<T> {
  class Peekable<T> {
    private final MyIterator<T> iter;
    private T next = null;
    private boolean isNextBuffered = false;
    private boolean atEnd = false;

    private Peekable(MyIterator<T> iter) {
      this.iter = iter;
    }

    private void advance() {
      if(atEnd) throw new NoSuchElementException();
      if(iter.hasNext()) {
        next = iter.next();
        isNextBuffered = true;
      } else {
        atEnd = true;
      }
    }
    private boolean hasNext() {
      if(atEnd) return false;
      if(!isNextBuffered) advance();
      return !atEnd;
    }
    private T next() {
      T next = peek();
      advance();
      return next;
    }
    private T peek() {
      if(hasNext()) return next;
      throw new NoSuchElementException();
    }
  }

  static <T> MyIterator<T> of(BooleanSupplier hasNext, Supplier<T> next) {
    return new MyIterator<T>() {
      public boolean hasNext() {
        return hasNext.getAsBoolean();
      }
      public T next() {
        return next.get();
      }
    };
  }

  static <T> MyIterator<T> of(Iterator<T> iter) {
    return of(iter::hasNext, iter::next);
  }

  static MyIterator<Integer> range(int start, int end) {
    int[] value = {start};
    return of(() -> value[0] < end, () -> value[0]++);
  }

  default <R> MyIterator<R> map(Function<? super T,? extends R> mapper) {
    return of(this::hasNext, () -> mapper.apply(this.next()));
  }

  default MyIterator<T> filter(Predicate<? super T> predicate) {
    Peekable<T> iter = new Peekable<T>(this);

    return new MyIterator<T>() {
      public boolean hasNext() {
        while(iter.hasNext() && !predicate.test(iter.peek())) iter.advance();
        return iter.hasNext();
      }
      public T next() {
        hasNext();
        return iter.next();
      }
    };
  }

  default MyIterator<T> merge(MyIterator<T> other, BiPredicate<? super T,? super T> smallerEqual) {
    Peekable<T> iter1 = new Peekable<T>(this);
    Peekable<T> iter2 = new Peekable<T>(other);

    return of(() -> iter1.hasNext() || iter2.hasNext(),
              () -> {
                if(!iter1.hasNext()) return iter2.next();
                else if(!iter2.hasNext()) return iter1.next();
                else {
                  T elem1 = iter1.peek();
                  T elem2 = iter2.peek();
                  return smallerEqual.test(elem1, elem2) ? iter1.next() : iter2.next();
                }
              });
  }
}

interface MyIterable<T> extends Iterable<T> {
  default Iterator<T> iterator() {
    return myIterator();
  }

  MyIterator<T> myIterator();

  static <T> MyIterable<T> of(Supplier<MyIterator<T>> myIterator) {
    return new MyIterable<T>() {
      public MyIterator<T> myIterator() {
        return myIterator.get();
      }
    };
  }

  static <T> MyIterable<T> of(Iterable<T> iterable) {
    return of(() -> MyIterator.of(iterable.iterator()));
  }

  static MyIterable<Integer> range(int start, int end) {
    return of(() -> MyIterator.range(start, end));
  }

  default <R> MyIterable<R> map(Function<? super T,? extends R> mapper) {
    return of(() -> this.myIterator().map(mapper));
  }

  default MyIterable<T> filter(Predicate<? super T> predicate) {
    return of(() -> this.myIterator().filter(predicate));
  }

  default MyIterable<T> merge(MyIterable<T> other, BiPredicate<? super T,? super T> smallerEqual) {
    return of(() -> this.myIterator().merge(other.myIterator(), smallerEqual));
  }
}


public class Test {
  public static void main(String[] args) {
    MyIterable<Integer> iterable = MyIterable.range(0, 10);

    MyIterable<Integer> iter1 = iterable.map(x -> 2 * x).filter(x -> x < 10);
    MyIterable<Integer> iter2 = iterable.map(x -> 2 * x + 1).filter(x -> x < 10);
    MyIterable<Integer> iterMerged = iter1.merge(iter2, (x, y) -> x <= y);

    iter1.forEach(System.out::println);
    System.out.println();
    iter2.forEach(System.out::println);
    System.out.println();
    iterMerged.forEach(System.out::println);
  }
}

答案 1 :(得分:1)

可能更具惯用性的“java”是用侦听器编写合并:

Good Response:
Age:10
Cache-Control:public, max-age=31104000
Connection:keep-alive
Date:Sat, 05 Sep 2015 16:15:51 GMT
ETag:"51dbe11a5fa320c4495221b69df1d860"
Server:AmazonS3
Via:1.1 b7bc8b4c398aa9f5a08980055c497334.cloudfront.net (CloudFront)
X-Amz-Cf-Id:4KE-cAoFrTmcjkRW3goZAImvyQE5i1Vl4KZyrWL8HyCk6GcJZ9N7Kw==
X-Cache:Hit from cloudfront

Bad Response:
Cache-Control:public, max-age=31104000
Connection:keep-alive
Date:Sat, 05 Sep 2015 16:16:42 GMT
ETag:"51dbe11a5fa320c4495221b69df1d860"
Last-Modified:Sat, 05 Sep 2015 16:07:41 GMT
Server:nginx/1.6.2
Via:1.1 45578d14a69df96accaab0d1aba82a5a.cloudfront.net (CloudFront)
X-Amz-Cf-Id:FGMRwDI0vOJQ7aPj83s-RGTO0fg_Zesu7FLo7Ia5vwCxcTZI97ri5A==
X-Cache:Miss from cloudfront

Good Request:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0    .8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,da;q=0.6
Cache-Control:max-age=0
Connection:keep-alive
Host:assets.runemadsen.com
If-Modified-Since:Sat, 05 Sep 2015 16:07:41 GMT
If-None-Match:"51dbe11a5fa320c4495221b69df1d860"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (    KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36

Bad Request:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0    .8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,da;q=0.6
Cache-Control:max-age=0
Connection:keep-alive
Host:images.runemadsen.com
If-Modified-Since:Sat, 05 Sep 2015 16:07:41 GMT
If-None-Match:"51dbe11a5fa320c4495221b69df1d860"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (    KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36