java - 对象列表 - 获取对象字段的不同计数
问题描述
对于对象列表,我必须检查(某些)字段:
- 该字段具有相同值的所有对象
- 该字段具有不同值的所有对象
class Person {
final String name;
final int age;
final int group;
public Person( final String name, final int age, final int group ) {
this.name = name;
this.age = age;
this.group = group;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
public int getGroup() {
return this.group;
}
}
public static <T> long distinctByField( final List<Person> personList, final Function<Person, T> field ) {
return personList.stream()
.map( field )
.distinct().count();
}
public static void main( final String[] args ) {
final List<Person> personList = Arrays.asList(
new Person( "Fred", 25, 1 ),
new Person( "Bill", 22, 1 ),
new Person( "Fred", 27, 1 ),
new Person( "Lisa", 25, 1 )
);
System.out.println( distinctByField( personList, Person::getName ) );
System.out.println( distinctByField( personList, Person::getAge ) );
System.out.println( distinctByField( personList, Person::getGroup ) );
}
通过流/不同/计数的结果,我可以与当前列表大小进行比较:
- if count == 1 :所有对象对该字段具有相同的值
- if count == list.size :该字段具有不同值的所有对象
缺点是,我必须为每个感兴趣的领域直播。
是否可以通过一个查询(针对感兴趣的字段列表)来做到这一点?
解决方案
可以使用反射:
public class ReflectionTest {
class Person {
final String name;
final int age;
final int group;
public Person(final String name, final int age, final int group) {
this.name = name;
this.age = age;
this.group = group;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
public int getGroup() {
return this.group;
}
}
@DisplayName("should determine distinct fields")
@Test
public void distinct() {
final List<Person> personList = Arrays.asList(new Person("Fred", 25, 1),
new Person("Bill", 22, 1),
new Person("Fred", 27, 1),
new Person("Lisa", 25, 1));
Map<String,Long> fieldCountMap = Stream.of("name", "age", "group")
.map(fieldName -> ReflectionUtils.findField(Person.class, fieldName))
.filter(Objects::nonNull)
.collect(Collectors.toMap(Field::getName, field -> personList.stream().map(person -> getField(field, person)).distinct().count()));
assertEquals(3,fieldCountMap.get("name"));
assertEquals(1,fieldCountMap.get("group"));
assertEquals(3,fieldCountMap.get("age"));
}
//extracted into a method because field.get throws a checked exception
Object getField(Field field, Person object) {
try {
return field.get(object);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
推荐阅读
- javascript - 单击按钮时在for循环中从数组中获取值
- r - 在 ggplot 中使用 percent(accuracy = 3L) 时,百分比不会四舍五入
- javascript - D3.js 中的 if else 语句用于自定义色标
- input - XY 图形的用户输入范围
- r - 调整以使条件面板仅在加载正确的文件时出现
- python - 如何按列值年份和月份分组以获得上个月的工资?
- javascript - JQuery Append 正在运行,但输入字段只是显示出来并消失
- eloquent - Laravel 7:从非主键制作外键
- javascript - 为什么具有对象值的变量总是与对象的值保持同步?
- amazon-web-services - aws ssm register-task-with-maintenance-window 报告错误为无效 JSON?