简体   繁体   中英

Java stream type issue

Somehow I can't use check on instanceof in stream. The problem occurred in test:

ArgumentCaptor<MyClass> arg = ArgumentCaptor.forClass(MyClass.class);
verify(modelService).save(arg.capture());

Method save called three times with different arguments(instances of different classes), and arg.getAllValues() returned SomeOtherClassObject1,SomeOtherClassObject2,MyClassObject

Stream bellow throws exception "SomeOtherClass can not be cast to MyClass"

MyClass argument = arg.getAllValues().stream()
.filter(v -> v instanceof MyClass)
.findFirst()
.get()

But if I use foreach everything works fine:

MyClass argument = null;
for(Object o : arg.getAllValues()) {
    if(o instanceof MyClass) {
        argument = (MyClass) o;
        break;
    }
}

Try with this casting . Because filter only filtering the stream according to your checking rule. This is one solution to resolve problem. Or use map to cast.

MyClass argument = ((MyClass)arg.getAllValues()
    .stream().
    .filter(v -> v instanceof MyClass)
    .findFirst()
    .get());

PS: map is more relevant to if your results more than one to apply for all. In your problem casting is more appropriate

The for each loop example shown in the question contains an explicit cast after the instanceof check. The following would be equivalent to that loop:

MyClass argument =
    arg.getAllValues()
        .stream()                            // Stream<SomeOtherClass>
        .filter(v -> v instanceof MyClass)   // Stream<SomeOtherClass>
        .map(MyClass.class::cast)            // Stream<MyClass>
        .findFirst()                         // Optional<MyClass>
        .orElse(null);                       // MyClass

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM