iterator
diff --git a/req/include/req_sketch.hpp b/req/include/req_sketch.hpp
index c8b7856..a96688a 100755
--- a/req/include/req_sketch.hpp
+++ b/req/include/req_sketch.hpp
@@ -260,6 +260,10 @@
    */
   string<Allocator> to_string(bool print_levels = false, bool print_items = false) const;
 
+  class const_iterator;
+  const_iterator begin() const;
+  const_iterator end() const;
+
 private:
   Allocator allocator_;
   uint16_t k_;
@@ -349,6 +353,23 @@
 
 };
 
+template<typename T, bool H, typename C, typename S, typename A>
+class req_sketch<T, H, C, S, A>::const_iterator: public std::iterator<std::input_iterator_tag, T> {
+public:
+  const_iterator& operator++();
+  const_iterator& operator++(int);
+  bool operator==(const const_iterator& other) const;
+  bool operator!=(const const_iterator& other) const;
+  std::pair<const T&, const uint64_t> operator*() const;
+private:
+  using CompactorsIterator = typename std::vector<Compactor, AllocCompactor>::const_iterator;
+  CompactorsIterator compactors_it_;
+  CompactorsIterator compactors_end_;
+  const T* compactor_it_;
+  friend class req_sketch<T, H, C, S, A>;
+  const_iterator(CompactorsIterator begin, CompactorsIterator end);
+};
+
 } /* namespace datasketches */
 
 #include "req_sketch_impl.hpp"
diff --git a/req/include/req_sketch_impl.hpp b/req/include/req_sketch_impl.hpp
index e6f4f71..d226c19 100755
--- a/req/include/req_sketch_impl.hpp
+++ b/req/include/req_sketch_impl.hpp
@@ -738,6 +738,59 @@
   }
 }
 
+template<typename T, bool H, typename C, typename S, typename A>
+auto req_sketch<T, H, C, S, A>::begin() const -> const_iterator {
+  return const_iterator(compactors_.begin(), compactors_.end());
+}
+
+template<typename T, bool H, typename C, typename S, typename A>
+auto req_sketch<T, H, C, S, A>::end() const -> const_iterator {
+  return const_iterator(compactors_.end(), compactors_.end());
+}
+
+// iterator
+
+template<typename T, bool H, typename C, typename S, typename A>
+req_sketch<T, H, C, S, A>::const_iterator::const_iterator(CompactorsIterator begin, CompactorsIterator end):
+compactors_it_(begin),
+compactors_end_(end),
+compactor_it_((*compactors_it_).begin())
+{}
+
+template<typename T, bool H, typename C, typename S, typename A>
+auto req_sketch<T, H, C, S, A>::const_iterator::operator++() -> const_iterator& {
+  ++compactor_it_;
+  if (compactor_it_ == (*compactors_it_).end()) {
+    ++compactors_it_;
+    if (compactors_it_ != compactors_end_) compactor_it_ = (*compactors_it_).begin();
+  }
+  return *this;
+}
+
+template<typename T, bool H, typename C, typename S, typename A>
+auto req_sketch<T, H, C, S, A>::const_iterator::operator++(int) -> const_iterator& {
+  const_iterator tmp(*this);
+  operator++();
+  return tmp;
+}
+
+template<typename T, bool H, typename C, typename S, typename A>
+bool req_sketch<T, H, C, S, A>::const_iterator::operator==(const const_iterator& other) const {
+  if (compactors_it_ != other.compactors_it_) return false;
+  if (compactors_it_ == compactors_end_) return true;
+  return compactor_it_ == other.compactor_it_;
+}
+
+template<typename T, bool H, typename C, typename S, typename A>
+bool req_sketch<T, H, C, S, A>::const_iterator::operator!=(const const_iterator& other) const {
+  return !operator==(other);
+}
+
+template<typename T, bool H, typename C, typename S, typename A>
+std::pair<const T&, const uint64_t> req_sketch<T, H, C, S, A>::const_iterator::operator*() const {
+  return std::pair<const T&, const uint64_t>(*compactor_it_, 1 << (*compactors_it_).get_lg_weight());
+}
+
 } /* namespace datasketches */
 
 #endif
diff --git a/req/test/req_sketch_test.cpp b/req/test/req_sketch_test.cpp
index e62f08a..436e6f9 100755
--- a/req/test/req_sketch_test.cpp
+++ b/req/test/req_sketch_test.cpp
@@ -72,6 +72,13 @@
   REQUIRE(quantiles[0] == 1);
   REQUIRE(quantiles[1] == 1);
   REQUIRE(quantiles[2] == 1);
+
+  unsigned count = 0;
+  for (auto it: sketch) {
+    REQUIRE(it.second == 1);
+    ++count;
+  }
+  REQUIRE(count == 1);
 }
 
 TEST_CASE("req sketch: repeated values", "[req_sketch]") {
@@ -168,6 +175,13 @@
   REQUIRE(sketch.get_max_value() == n - 1);
   REQUIRE(sketch.get_rank_lower_bound(0.5, 1) < 0.5);
   REQUIRE(sketch.get_rank_upper_bound(0.5, 1) > 0.5);
+
+  unsigned count = 0;
+  for (auto it: sketch) {
+    REQUIRE(it.second >= 1);
+    ++count;
+  }
+  REQUIRE(count == sketch.get_num_retained());
 }
 
 TEST_CASE("req sketch: stream serialize-deserialize empty", "[req_sketch]") {
@@ -451,15 +465,15 @@
   REQUIRE(sketch.get_rank(60) == Approx(0.5).margin(0.01));
 }
 
-//TEST_CASE("for manual comparison with Java") {
-//  req_sketch<float, true> sketch(12);
-//  for (size_t i = 0; i < 100000; ++i) sketch.update(i);
-//  sketch.merge(sketch);
-//  std::ofstream os;
-//  os.exceptions(std::ios::failbit | std::ios::badbit);
-//  os.open("req_float_hra_12_100000_merged.sk", std::ios::binary);
-//  sketch.get_quantile(0.5); // force sorting level 0
-//  sketch.serialize(os);
-//}
+TEST_CASE("for manual comparison with Java") {
+  req_sketch<float, true> sketch(12);
+  for (size_t i = 0; i < 100000; ++i) sketch.update(i);
+  sketch.merge(sketch);
+  std::ofstream os;
+  os.exceptions(std::ios::failbit | std::ios::badbit);
+  os.open("req_float_hra_12_100000_merged.sk", std::ios::binary);
+  sketch.get_quantile(0.5); // force sorting level 0
+  sketch.serialize(os);
+}
 
 } /* namespace datasketches */