do-while with Java8-Optional [英] do-while with Java8-Optional

查看:124
本文介绍了do-while with Java8-Optional的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的一些项目中,我经常使用do-while-checkNextForNull-getNext循环模式(不知道它是否有正式名称)。但是在Java8中,使用Optional比在客户端代码中检查空引用更清晰。但是当在这个循环模式中使用Optional时,代码有点冗长和丑陋,但是因为Optional有一些方便的方法,我希望必须存在比我下面提到的更清晰的方法。

I'm frequently using the do-while-checkNextForNull-getNext looping pattern (don't know if there is an official name for it) in some of my projects. But in Java8, the use of Optional is considered as cleaner code than checking for null references in client-code. But when using Optional in this looping pattern, the code gets a bit verbose and ugly, but because Optional has some handy methodS, I would expect that there must exist a cleaner way than the one I came up with below.

示例:

给定以下类别。

class Item {
    int nr;

    Item(nr) {
        this.nr = nr;
        // an expensive operation
    }

    Item next() {
        return ...someCondition....
            ? new Item(nr + 1)
            : null;
    }
}

其中第一项始终为nr == 1并且每个项目确定下一个项目,并且您不想创建不必要的新项目。

In which the first item always has nr==1 and each item determines the next item, and you don't want to create unnecessary new items.

我可以使用以下循环do-while-checkNextForNull-getNext模式客户代码:

I can use the following looping do-while-checkNextForNull-getNext pattern in client-code:

Item item = new Item(1);
do {
    // do something with the item ....
} while ((item = item.next()) != null);

使用Java8-Optional,给定的类变为:

With Java8-Optional, the given class becomes:

class Item {
    ....

    Optional<Item> next() {
        return ...someCondition....
            ? Optional.of(new Item(nr + 1))
            : Optional.empty();
    }
}

然后执行do-while-checkNextForNull-getNext循环模式变得有点丑陋和冗长:

And then the do-while-checkNextForNull-getNext looping pattern becomes a bit ugly and verbose:

Item item = new Item(1);
do {
    // do something with the item ....
} while ((item = item.next().orElse(null)) != null);

orElse(null))!= null 部分感觉不舒服。

我寻找其他类型的循环,但没有找到更好的循环。是否有更清洁的解决方案?

I have looked for other kind of loops, but haven't found a better one. Is there a cleaner solution?

可以使用for-each循环同时避免空引用(使用空引用被认为是一种不好的做法)。该解决方案由Xavier Delamotte提出,不需要Java8-Optional。

It is possible to use a for-each loop while at the same time avoiding null-references (the use of null-references is considered as a bad practice). This solution has been proposed by Xavier Delamotte, and doesn't need Java8-Optional.

使用泛型迭代器实现:

public class Item implements Iterable<Item>, Iterator<Item> {
    int nr;

    Item(int nr) { 
        this.nr = nr;
        // an expensive operation
    }

    public Item next() {
        return new Item(nr + 1);
    }

    public boolean hasNext() {
        return ....someCondition.....;
    }

    @Override
    public Iterator<Item> iterator() {
        return new CustomIterator(this);
    }
}

class CustomIterator<T extends Iterator<T>> implements Iterator<T> {
    T currentItem;
    boolean nextCalled;

    public CustomIterator(T firstItem) {
        this.currentItem = firstItem;
    }

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

    @Override
    public T next() {
        if (! nextCalled) {
            nextCalled = true;
            return currentItem;
        } else {
            currentItem = currentItem.next();
            return currentItem;
        }
    }
}

然后客户端代码变得非常简单/ clean:

Then client code becomes very simple/clean:

for (Item item : new Item(1)) {
    // do something with the item ....
}

虽然这可能被视为违反了迭代器合约因为 new Item(1)对象包含在循环中,而通常,for循环会立即调用next(),从而跳过第一个对象。换句话说:对于第一个对象,违反了next(),因为它返回第一个对象本身。

Although this may be seen as a violation of the Iterator contract because the new Item(1) object is included in the loop, whereas normally, the for loop would immediately call next() and thus skipping the first object. In other words: for the first object, next() is violated because it returnS the first object itself.

推荐答案

你可以做类似这样的事情:

You can do something like this :

Optional<Item> item = Optional.of(new Item(1));
do {
    Item value = item.get();
    // do something with the value ....
} while ((item = value.next()).isPresent());

或(以避免额外变量):

or (to avoid the extra variable) :

Optional<Item> item = Optional.of(new Item(1));
do {
    // do something with item.get() ....
} while ((item = item.get().next()).isPresent());

这篇关于do-while with Java8-Optional的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆