Franz-kun
Franz-kun

Reputation: 59

Java 8 Iterator stream filter NoSuchElementException

    public static double getAttackSpeed(ItemStack item) {
    Attributes ab = new Attributes(item);
    for(Attributes.Attribute attribute : ab.values())
        Flawlord.log(attribute.getName());
    return FlawlordHelper.stream(ab.values()).filter(a -> a.getAttributeType().equals(Attributes.AttributeType.GENERIC_ATTACK_SPEED)).findFirst().get().getAmount();
}

this doesnt work

    public static int getDamage(ItemStack item) {
    Attributes ab = new Attributes(item);
    int dmg = 0;
    for(Attributes.Attribute attribute : ab.values())
        if (attribute.getAttributeType() == Attributes.AttributeType.GENERIC_ATTACK_DAMAGE)
            dmg = (int) attribute.getAmount();
    return dmg;
}

this works

hello. can someone explain to me why the latter works, but the first not? maybe im just not getting it, idk. i think perhaps .equals() doesnt work here?

if i use the first one with lambda, i get an exception "NoSuchElementException: No value present".

Upvotes: 0

Views: 1436

Answers (2)

Sleiman Jneidi
Sleiman Jneidi

Reputation: 23319

You are not supposed to call get on an Optional because there might be not result and a NoSuchElementException will be thrown which makes as bad as NPE, you can use Optional.map or Optional.isPresent instead.

findFirst returns an Optional because there is no guarantee that an element will be found.

Iterators are different, they only iterate if there is at least one element.

Upvotes: 1

wero
wero

Reputation: 32980

If the list/iterator/stream does not contain an element which matches the filter then the Optional returned by findFirst will be empty and throw that exception if you access the value via get.

Upvotes: 2

Related Questions