【问题标题】:Implement a Java Iterator for a nested HashMap in which an element can be any of 1) an Integer or, 2) another nested HashMap or, 3) an empty HashMap为嵌套的 HashMap 实现 Java 迭代器,其中元素可以是以下任何一种:1) 整数或,2) 另一个嵌套的 HashMap,或,3) 空的 HashMap
【发布时间】:2015-05-02 05:42:07
【问题描述】:

如标题中所述,我们如何才能做到这一点?我觉得它应该类似于树遍历,但我不知道如何做到这一点。

    Map<Integer, Object> map = new HashMap<>();     

    map.put(1, 1);
    map.put(2, 2);


    map.put(3, new HashMap<Integer, Object>());
    Map<Integer, Object> m1 = (Map<Integer, Object>)map.get(3);
    m1.put(4, 4);
    m1.put(5, new HashMap<Integer, Object>());      
    m1.put(6, 6);

    Map<Integer, Object> m2 = (Map<Integer, Object>)m1.get(5);
    m2.put(8, 8);
    m2.put(9, 9);

    map.put(7, new HashMap<Integer, Object>());

在这个例子中,前两个“值”是两个 Integer,第三个“值”是一个嵌套的 HashMap,它包含两个 Integer 和一个“更深层次”的嵌套 HashMap。关于key 7,我想说“value”也可以是一个空的HashMap——因为这是一道面试题,我猜这种“empty value”的可能性可能会影响next()或者hasNext()的实现?

【问题讨论】:

  • 事情很简单,直到您尝试解决它们,付出努力并且确信,您会想出一些逻辑。分享您的努力,我们会在您遇到困难时提供帮助。
  • HashMap 包含 key - value 对。那么你如何在你的问题中定义一个元素?是Integerkey 还是HashMapvalue
  • 对不起,这里的元素我的意思是一个值..
  • 更多细节:对于嵌套 HashMap 中的每个键值对,key 总是一个 Integer,并且 value 可以是 1) Integer,2) 另一个嵌套 HashMap,或 3) 空哈希映射。 --- 如果您继续调用 next() 函数,迭代器的目的是输出所有整数“值”。 --- 希望这个澄清是清楚的......
  • 你怎么能声明这样一个HashMap?你能发布你如何声明HashMap吗?此外,当您回答任何评论时,请使用 @ 立即通知该人。

标签: java iterator hashmap


【解决方案1】:

实际上有很多不同的解决方案。 到目前为止最短的是这里,它使用了 Streams。

@SuppressWarnings("unchecked")
static <T> Stream<T> mapTraversalStream(Map<Integer, T> map) {
  return map.values().stream().flatMap(value -> {
    if(value instanceof Map) {
      return mapTraversalStream((Map<Integer, T>)value);
    } else {
      return Stream.of(value);
    }
  });
}

static <T> Iterator<T> mapTraversalIterator(Map<Integer, T> map) {
  return mapTraversalStream(map).iterator();
}

编辑:

如果您不能使用 Java 8,您可以定义自己的 map 和 flatten 方法。

@SuppressWarnings("unchecked")
static <T> Iterator<T> mapTraversalIterator(Map<Integer, T> map) {
  return flatten(map(map.values().iterator(), new Function<T, Iterator<T>>() {
      public Iterator<T> apply(T value) {
        if(value instanceof Map) {
          return mapTraversalIterator((Map<Integer, T>)value);
        } else {
          return Collections.singleton(value).iterator();
        }
      }
  }));
}

interface Function<A, B> {
  B apply(A a);
}

static <A, B> Iterator<B> map(Iterator<A> iter, Function<A, B> op) {
  return new Iterator<B>() {
    public boolean hasNext() {
      return iter.hasNext();
    }
    public B next() {
      return op.apply(iter.next());
    }
  };
}

static <A> Iterator<A> flatten(Iterator<Iterator<A>> iter) {
  return new Iterator<A>() {
    private Iterator<A> next = null;

    public boolean hasNext() {
      while(iter.hasNext() && (next == null || !next.hasNext())) {
        next = iter.next();
      }
      if(next == null || !next.hasNext()) return false;
      else return true;
    }
    public A next() {
      if(!hasNext()) throw new NoSuchElementException();
      return next.next();
    }
  };
}

【讨论】:

  • 谢谢。不使用 Java 8 的新特性是否可以做到这一点?
  • 当然,我在答案中添加了一个示例。
猜你喜欢
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-04
相关资源
最近更新 更多