在Java中将单个元素转换为Iterable

问题描述 投票:0回答:1

在 C# 中,我可以将单个元素转换为像这样的

IEnumerable<>
(此处使用扩展方法):

static class Extensions
{
    static IEnumerable<T> Yield<T>(this T t)
    {
        yield return t;
    }
}

当我需要在某处输入

IEnumerable<>
但只有一个元素时,我会使用它,如下所示:

var myList = new List<string>("foo".Yield());

在Java中是否有一些等效的方法可以做到这一点?

我对在堆上从像

这样的元素实际创建一个
Iterable<>

不感兴趣
List<String> myIterable = new ArrayList<String>();
myIterable.add("foo");

因为我已经知道那种解决方案;我想知道 Java 是否可以像 C# 一样强大地处理可枚举/可迭代(C# 有 Linq 和yield return,Java 有 Streams)并且是惰性的。

java c# iterable enumerable
1个回答
5
投票

最简单的方法是使用

Collections.singleton()
Collections.singletonList()

Collections.singleton(1);
Collections.singletonList("");

返回的集合在这两种情况下都是不可变的,它们仅由实际元素支持。从某种意义上说,它们“不是”真正的集合,因为它们只允许迭代和其他非修改操作。 或者你可以自己实现

Iterator

Iterable
,尽管这会在某种程度上重新实现上述内容(jdk已经提供了类似/相同的功能)。
public class SingleElementIterator<T> implements Iterator<T> {

  private final T element;
  private boolean hasNext;

  public SingleElementIterator(T element) {
    this.element = element;
    this.hasNext = true;
  }

  @Override
  public boolean hasNext() {
    return this.hasNext;
  }

  @Override
  public T next() {
    if (this.hasNext) {
      this.hasNext = false;
      return this.element;
    }
    throw new NoSuchElementException();
  }
}

public class SingleElementIterable<T> implements Iterable<T> {

  private final T element;

  public SingleElementIterable(T element) {
    this.element = element;
  }

  @Override
  public Iterator<T> iterator() {
    return new SingleElementIterator<>(this.element);
  }
}
示例:

public class Temp { public static void main(String[] args) { Iterable<String> iterable = new SingleElementIterable<>("abc"); for (String string : iterable) { System.out.println(string); } } }

© www.soinside.com 2019 - 2024. All rights reserved.