可能重复:
为什么Java的迭代器不是Iterable?
据我所知,foreach循环是Java 5中添加的语法糖.所以
Iterable<O> iterable;
for(O o : iterable) {
// Do something
}
Run Code Online (Sandbox Code Playgroud)
将基本上产生相同的字节码
Iterable<O> iterable;
for(Iterator<O> iter = iterable.iterator(); iter.hasNext(); /* NOOP */) {
O o = iter.next();
// Do something
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我首先没有迭代,但只有一个迭代器(比如,因为一个类提供了两个不同的迭代器),我不能使用语法sugar foreach循环.显然我仍然可以做普通的旧式迭代.但是,我其实想做:
Iterator<O> iter;
for(O o : iter /* Iterator<O>, not Iterable<O>! */) {
// Do something
}
Run Code Online (Sandbox Code Playgroud)
当然我可以做假的Iterable:
class Adapter<O> implements Iterable<O> {
Iterator<O> iter;
public Adapter(Iterator<O> iter) {
this.iter = iter;
}
@Override
public Iterator<O> iterator() {
return iter; …Run Code Online (Sandbox Code Playgroud) 在Java 5及更高版本中,你有foreach循环,它可以在任何实现的东西上神奇地工作Iterable:
for (Object o : list) {
doStuff(o);
}
Run Code Online (Sandbox Code Playgroud)
但是,Enumerable仍然没有实现Iterable,这意味着迭代Enumeration你必须执行以下操作:
for(; e.hasMoreElements() ;) {
doStuff(e.nextElement());
}
Run Code Online (Sandbox Code Playgroud)
有谁知道有没有理由Enumeration仍然没有实现Iterable?
假设我们有一个Iterator<Integer> iterator.因为Iterable是一个功能界面,我们可以写:
Iterable<Integer> iterable = () -> iterator;
Run Code Online (Sandbox Code Playgroud)
那么我们当然可以iterable用作增强的for循环表达式:
for (Integer i : iterable) foo(i);
Run Code Online (Sandbox Code Playgroud)
那么为什么呢
for (Integer i : () -> iterator) foo(i);
Run Code Online (Sandbox Code Playgroud)
不允许?(导致以下编译器错误:)
error: lambda expression not expected here
for (Integer i : () -> iterator) foo(i);
^
Run Code Online (Sandbox Code Playgroud)
使目标类型显式为
for (Integer i : (Iterable<Integer>) () -> iterator) foo(i);
Run Code Online (Sandbox Code Playgroud)
显然有效,但为什么编译器不能推断出λ-expression的目标类型?从表达式是λ表示法的事实来看,编译器不应该清楚目标类型不能是一个Array,因此必须是Iterable?
这只是语言设计师的疏忽,还是我还缺少其他的东西?
我读了为什么Java的迭代器不是Iterable?而为什么不枚举可迭代?,但我仍然不明白为什么这样:
void foo(Iterator<X> it) {
for (X x : it) {
bar(x);
baz(x);
}
}
Run Code Online (Sandbox Code Playgroud)
没有成功.换句话说,除非我遗漏了某些东西,否则上面可能是一个很好的有效语法糖:
void foo(Iterator<X> it) {
for (X x; it.hasNext();) {
x = it.next();
bar(x);
baz(x);
}
}
Run Code Online (Sandbox Code Playgroud) Scala是否提供内置的类,实用程序,语法或其他机制来转换(通过换行)具有Iterable的Iterator?
例如,我有一个迭代器[Foo],我需要一个Iterable [Foo],所以目前我是:
val foo1: Iterator[Foo] = ....
val foo2: Iterable[Foo] = new Iterable[Foo] {
def elements = foo1
}
Run Code Online (Sandbox Code Playgroud)
这看起来很丑陋而且没必要.什么是更好的方式?
我认为这Iterator.copy()将是一个非常方便的功能.您可以以更好的方式实现迭代器过滤器.
例如,Googles Java Collection中filter(和类似的)函数使用的唯一原因UnmodifiableIterator(只是Iterator没有remove)是因为你不能实现这样的过滤器,Iterator否则无法在某些时候复制它.(真的,使用当前界面是不可能的;试试吧.)
另一个优点是你可以在for-each-loop中使用迭代器:因为可复制的迭代器也可以自动迭代.另见这个问题.目前,主要的设计理由不允许这样做是因为Iterator它实现Iterable并Iterator<T> iterator() { return this; }会使无效迭代器.通过使用一个copy函数,它就像它一样简单Iterator<T> iterator() { return copy(); }并且它不会使原始迭代器无效.因此,没有理由不允许这样做.
有什么缘故吗?只是为了减少实现它的复杂性?
我正在寻找一种为多个枚举构建包装器的方法。说你有
public enum Enum1 {
A,B,C
}
public enum Enum2 {
ONE,TWO,THREE
}
Run Code Online (Sandbox Code Playgroud)
我想要一个带有文字的新枚举
(A,ONE), (A,TWO), (A,THREE), (B,ONE), ...
Run Code Online (Sandbox Code Playgroud)
整个事情都是通用的,所以我不必知道 Enum1 和 Enum2。有没有办法构建它,甚至将其扩展到 n 个枚举?
或者我应该寻找其他通用方法来建模?
我有一个函数myFunction的Function<Integer, T>,我想构造一个对象mylist的大小size,实现List<T>(或者某种不可变列表界面),通过功能的支持,在这个意义上mylist.get(i) == myFunction.apply(i).
我可以手动执行此操作,但是有一些(Guava)代码也可以这样做吗?
如果我们执行以下操作,则会收到错误:
class FGH{
public static Iterator reverse(List list) {
Collections.reverse(list);
return list.iterator();
}
public static void main(String[] args) {
List list = new ArrayList();
list.add("1"); list.add("2"); list.add("3");
/*for(Iterator it:reverse(list))
Iterator it=reverse(list);*/
for (Object obj: reverse(list))
System.out.print(obj + ", ");}}
Run Code Online (Sandbox Code Playgroud)
但是如果我们像这样修改代码我们就不会得到错误,那么它是否意味着我们不能迭代Iterator类型的对象?:
class FGH{
public static Iterator reverse(List list) {
Collections.reverse(list);
return list.iterator();
}
public static void main(String[] args) {
List list = new ArrayList();
list.add("1"); list.add("2"); list.add("3");
Iterator it=reverse(list);
while(it.hasNext()){
Object obj=it.next();
System.out.println(obj);
}
}}
Run Code Online (Sandbox Code Playgroud) 输入:
Hi. I am John.
My name is John. Who are you ?
Run Code Online (Sandbox Code Playgroud)
输出:
Hi
I am John
My name is John
Who are you
Run Code Online (Sandbox Code Playgroud) 我正在用org.json中的lib解析这个JSON字符串,我无法理解为什么我将下面的输出放到日志中.
ArrayList<String> al = new ArrayList<String>();
JSONObject demo = new JSONObject("{\"00408C88A2E6\":{\"id\":\"00408C88A2E6\",\"name\":\"Lab\"},\"00408C91188B\":{\"id\":\"00408C91188B\",\"name\":\"Lab1\"},\"00408C944B99\":{\"id\":\"00408C944B99\",\"name\":\"Lato1\"},\"00408C944BA0\":{\"id\":\"00408C944BA0\",\"name\":\"Lato\"}}");
Iterator<String> iterator = demo.keys();
while (iterator.hasNext() ){
al.add((String)iterator.next());
Log.i(LOG_TAG, "size al into while " + al.size());
Log.i(LOG_TAG, "MAC " + iterator.next() + " for the user " + userId);
}
Run Code Online (Sandbox Code Playgroud)
记录输出
07-12 08:55:34.056: INFO/parse(285): size al into while 1
07-12 08:55:34.056: INFO/parse(285): MAC 00408C91188B for the user nweb
07-12 08:55:34.066: INFO/parse(285): size al into while 2
07-12 08:55:34.066: INFO/parse(285): MAC 00408C944B99 for the user nweb
07-12 08:55:34.066: INFO/parse(285): size …Run Code Online (Sandbox Code Playgroud) 我正在尝试将词性功能的输出传递到index-words函数中,并使用( - >)线程宏打印结果输出:
(defn parts-of-speech []
(seq (. POS values)))
(defn index-words [pos]
(iterator-seq (. dict getIndexWordIterator pos)))
(-> (parts-of-speech) index-words println)
Run Code Online (Sandbox Code Playgroud)
但是index-words func返回一个iterator-seq,我不知道如何在这个上下文中迭代它,因为我是Clojure的新手.
编辑:根据建议更新代码.
更新:
感谢@kotarak和@ jayunit100的回答以及来自@ sw1nn和@ marko-topolnik的评论,我至少有两个有效的变体:
(->> (parts-of-speech) (map index-words) (map println) doall)
(doseq [w (map index-words (parts-of-speech))]
(println w))
Run Code Online (Sandbox Code Playgroud)
我来自一个命令性的背景,我的这个问题的目标是理解线程宏,试图编写更多惯用的Clojure(在尝试使用线程宏之前,我使用multiple doseq和lets 循环遍历每个序列).
从评论来看,似乎线程宏可能不是最惯用的方式,但我仍然希望看到如何使它工作,所以我可以填补这个理解的空白.
此外,(parts-of-speech)返回一个包含四个项目的序列,如果您执行a (println (count w))而不是(println w),则可以看到它打印四个序列的计数而不是一个连续序列:
(doseq [w (map index-words (parts-of-speech))]
(println (count w)))
;= 117798
;= 11529
;= 21479
;= 4481
Run Code Online (Sandbox Code Playgroud)
你如何修改上面的内容来打印一个连续的单词流而不是打印四个序列的内容?
BTW:上面的代码包含了MIT Java …
说实话,我不太确定自己是否理解这个任务:)我被告知创建类MySimpleIt,它实现了Iterator和Iterable,并允许运行提供的测试代码.对象的参数和变量不能是集合或数组.
代码 :
MySimpleIt msi=new MySimple(10,100,
MySimpleIt.PRIME_NUMBERS);
for(int el: msi)
System.out.print(el+" ");
System.out.println();
msi.setType(MySimpleIterator.ODD_NUMBERS);
msi.setLimits(15,30);
for(int el: msi)
System.out.print(el+" ");
System.out.println();
msi.setType(MySimpleIterator.EVEN_NUMBERS);
for(int el: msi)
System.out.print(el+" ");
System.out.println();
Run Code Online (Sandbox Code Playgroud)
我应该得到的结果:
11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
15 17 19 21 23 25 27 29
16 18 20 22 24 26 28 30
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
import java.util.Iterator;
interface MySimpleIterator{
static int ODD_NUMBERS=0;
static int EVEN_NUMBERS = 1;
static …Run Code Online (Sandbox Code Playgroud)