From fd70b5f0e183dfece2421434e89a01bc28ffef8b Mon Sep 17 00:00:00 2001 From: Giorgos Stamatelatos Date: Thu, 5 Jul 2018 12:58:08 +0300 Subject: [PATCH] Rewrite scala stream demos --- demo-scala/src/UnweightedStream.scala | 28 ++++++++++++++++---------- demo-scala/src/WeightedStream.scala | 29 ++++++++++++++++----------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/demo-scala/src/UnweightedStream.scala b/demo-scala/src/UnweightedStream.scala index 8497a49..1b98c9a 100644 --- a/demo-scala/src/UnweightedStream.scala +++ b/demo-scala/src/UnweightedStream.scala @@ -1,17 +1,17 @@ import java.util.Random -import SamplingIterator._ +import SamplingTraversableOnce._ import gr.james.sampling.{RandomSampling, WatermanSampling} import scala.collection.JavaConverters._ /** - * Extension of the [[Iterator]] with the sample method. + * Extension of [[TraversableOnce]] with the sample method. * - * @param it the source iterator + * @param it the source * @tparam T the element type */ -class SamplingIterator[T](val it: Iterator[T]) { +class SamplingTraversableOnce[T](val it: TraversableOnce[T]) { private val foldOperation = (rs: RandomSampling[T], i: T) => { rs.feed(i) @@ -19,26 +19,32 @@ class SamplingIterator[T](val it: Iterator[T]) { } /** - * Samples this iterator using the provided algorithm. + * Samples this iterator using the provided algorithm and returns a copy of the reservoir. * * @param rs the sampling algorithm * @return a [[List]] containing the sampled elements + * @throws NullPointerException if rs is null + * @throws IllegalArgumentException if rs is not empty */ - def sample(rs: RandomSampling[T]): List[T] = it.foldLeft(rs)(foldOperation).sample().asScala.toList + def sample(rs: RandomSampling[T]): List[T] = { + require(rs.sample().isEmpty) + it.foldLeft(rs)(foldOperation).sample().asScala.toList + } } /** - * The [[SamplingIterator]] companion object with the iteratorToSamplingIterator implicit conversion. + * The [[SamplingTraversableOnce]] companion object with the traversableOnceImplicitConversion implicit + * conversion. */ -object SamplingIterator { - implicit def iteratorToSamplingIterator[T](s: Iterator[T]): SamplingIterator[T] = - new SamplingIterator(s) +object SamplingTraversableOnce { + implicit def traversableOnceImplicitConversion[T](s: TraversableOnce[T]): SamplingTraversableOnce[T] = + new SamplingTraversableOnce(s) } /** * Unweighted random sampling using functional constructs. */ object UnweightedStream extends App { - val sample = (0 until 20).iterator.sample(new WatermanSampling[Int](5, new Random())) + val sample = (0 until 20).sample(new WatermanSampling[Int](5, new Random())) println(sample) } diff --git a/demo-scala/src/WeightedStream.scala b/demo-scala/src/WeightedStream.scala index 1352058..2db5387 100644 --- a/demo-scala/src/WeightedStream.scala +++ b/demo-scala/src/WeightedStream.scala @@ -1,17 +1,17 @@ import java.util.Random -import WeightedSamplingIterator._ +import WeightedSamplingTraversableOnce._ import gr.james.sampling.{ChaoSampling, WeightedRandomSampling} import scala.collection.JavaConverters._ /** - * Extension of the [[Iterator]] with the sample method. + * Extension of [[TraversableOnce]] with the sample method. * - * @param it the source iterator + * @param it the source * @tparam T the element type */ -class WeightedSamplingIterator[T](val it: Iterator[(T, Double)]) { +class WeightedSamplingTraversableOnce[T](val it: TraversableOnce[(T, Double)]) { private val foldOperation = (rs: WeightedRandomSampling[T], i: (T, Double)) => { rs.feed(i._1, i._2) @@ -19,21 +19,26 @@ class WeightedSamplingIterator[T](val it: Iterator[(T, Double)]) { } /** - * Samples this iterator using the provided algorithm. + * Samples this iterator using the provided algorithm and returns a copy of the reservoir. * * @param wrs the sampling algorithm * @return a [[List]] containing the sampled elements + * @throws NullPointerException if wrs is null + * @throws IllegalArgumentException if wrs is not empty */ - def sample(wrs: WeightedRandomSampling[T]): List[T] = it.foldLeft(wrs)(foldOperation).sample().asScala.toList + def sample(wrs: WeightedRandomSampling[T]): List[T] = { + require(wrs.sample().isEmpty) + it.foldLeft(wrs)(foldOperation).sample().asScala.toList + } } /** - * The [[WeightedSamplingIterator]] companion object with the iteratorToWeightedSamplingIterator implicit - * conversion. + * The [[WeightedSamplingTraversableOnce]] companion object with the traversableOnceImplicitConversion + * implicit conversion. */ -object WeightedSamplingIterator { - implicit def iteratorToWeightedSamplingIterator[T](s: Iterator[(T, Double)]): WeightedSamplingIterator[T] = - new WeightedSamplingIterator(s) +object WeightedSamplingTraversableOnce { + implicit def traversableOnceImplicitConversion[T](s: TraversableOnce[(T, Double)]): WeightedSamplingTraversableOnce[T] = + new WeightedSamplingTraversableOnce(s) } /** @@ -47,6 +52,6 @@ object WeightedStream extends App { "random" -> 3.0, "sampling" -> 4.0, "reservoir" -> 5.0 - ).iterator.sample(new ChaoSampling[String](2, new Random)) + ).sample(new ChaoSampling[String](2, new Random)) println(sample) }