java - 将元素从“流中流”映射到 Set
问题描述
我是 Java 流的新手。
我有一个包含 n 个类的数组。
这些类有几个带有特定注释的字段(SomeAnnotationClass.class)
我正在尝试获取使用此特定注释注释的所有字段注释值的集合。如果该字段没有注释,我想要该字段的名称。
所以我尝试了这样的事情:
Stream.of(clazzes).map( c ->
Stream.of((c.getDeclaredFields()))
.map(
field ->
Optional.ofNullable(
field.getDeclaredAnnotation(SomeAnnotationClass.class).value())
.orElse(field.getName())).collect(Collectors.toSet())).collect(Collectors.toSet());
2个问题:
- 由于收集了 2 次,我得到了 Set<Set> 而不是 Set。
- 如果注释不存在但调用 SomeAnnotationClass.class.value() 我会得到一个 Nullpointer
我可以通过流优雅地实现这一点吗?
解决方案
一组集合应该被展平:
// in Main.java
public static Set<String> getValuesOrNames(Class ... clazzes) {
return Arrays.stream(clazzes) // convert array to Stream<Class>
.flatMap(c -> Arrays.stream(c.getDeclaredFields())) // convert array of fields Stream<Field>
.map(field -> Optional.ofNullable(field.getAnnotation(SomeAnnotationClass.class))
.map(SomeAnnotationClass::value) // assuming SomeAnnotationClass has value method
.orElse(field.getName())
)
.collect(Collectors.toSet());
}
测试
// annotation class
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SomeAnnotationClass {
String value() default "";
}
import java.util.*;
import java.util.stream.Collectors;
import lombok.Data;
public class Main {
public static void main(String[] args) {
System.out.println(getValuesOrNames(Something.class, Main.class));
}
@Data
public static class Something {
@SomeAnnotationClass(value = "String foo")
private String foo;
@SomeAnnotationClass
private String emptyFoo;
private String bar;
@SomeAnnotationClass(value = "int id")
private int id;
}
}
输出
[, String foo, bar, int id]
推荐阅读
- c++ - 根据标准,array-of-arrays-of-T 是否在 C/C++ 中强制转换为 T 指针?
- sql - 当存在具有特定条件的重复项时,如何仅计算一行?
- python - 使用 pynput 监视按键时出现按键重复的问题
- reactjs - React-Router LinkContainer to={..} 不读取状态变量
- google-analytics - 将 Quantcast Choice (TCF v2) 与 Google Analytics 集成?
- android - 运行时获取 Gradle 子项目名称 :subproject:task
- linux - 如何设置 GraalVM 环境变量?
- javascript - 为什么我对 querySelectorAll('.select') 的调用返回 null?
- aspnetboilerplate - ApplicationService 端点上的 FluentValidation
- c# - 我正在尝试使用以下代码使用 Browserstack 标记测试通过或失败