写了动态指定单个字段的分组,但是 MethodHandle handle = lookup.findGetter(this.getT().getClass(), fieldName, String.class); 会报错找不到字段,我确定字段没写错
public class CollectionsUtils<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
public CollectionsUtils(T t) {
this.t = t;
}
//多字段排序
public <T> Map<List<String>, List<T>> DynamicGroupListByFiled(List<T> data, String[] groupByFieldNames) {
final MethodHandles.Lookup lookup = MethodHandles.lookup();
List<MethodHandle> handles =
Arrays.stream(groupByFieldNames)
.map(field -> {
try {
return lookup.findGetter(this.getT().getClass(), field, String.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}).collect(Collectors.toList());
return data.stream().collect(Collectors.groupingBy(
d -> handles.stream()
.map(handle -> {
try {
return (String) handle.invokeExact(d);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}).collect(Collectors.toList())
));
}
//按某字段分组后统计数量
public Map<String, Long> DynamicGroupListByFiled(List<T> data, String fieldName) {
final MethodHandles.Lookup lookup = MethodHandles.lookup();
try {
MethodHandle handle = lookup.findGetter(this.getT().getClass(), fieldName, String.class);
return data.stream().collect(Collectors.groupingBy(
d -> {
try {
return (String) handle.invokeExact(d);
} catch (Throwable e) {
throw new RuntimeException(e);
}
} ,Collectors.counting()));
}
catch (Throwable e)
{
throw new RuntimeException();
}
}
//算不定字段平均值
public Double getDynamicFieldAverage(List<T> data, String fieldName) {
final MethodHandles.Lookup lookup = MethodHandles.lookup();
try {
MethodHandle handle = lookup.findGetter(this.getT().getClass(), fieldName, String.class);
return data.stream().mapToDouble(d -> {
try {
return (Double) handle.invokeExact(d);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
).average().getAsDouble();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@Test
public void testCollectionUtils()
{
List<EsFitnessTestRecordDO> list = new ArrayList<>();
list.add(new EsFitnessTestRecordDO().setBmiRating("优秀").setBmiScore(90D));
list.add(new EsFitnessTestRecordDO().setBmiRating("优秀").setBmiScore(92D));
list.add(new EsFitnessTestRecordDO().setBmiRating("优秀").setBmiScore(94D));
list.add(new EsFitnessTestRecordDO().setBmiRating("良好").setBmiScore(80D));
list.add(new EsFitnessTestRecordDO().setBmiRating("良好").setBmiScore(82D));
list.add(new EsFitnessTestRecordDO().setBmiRating("良好").setBmiScore(84D));
list.add(new EsFitnessTestRecordDO().setBmiRating("合格").setBmiScore(70D));
list.add(new EsFitnessTestRecordDO().setBmiRating("合格").setBmiScore(76D));
list.add(new EsFitnessTestRecordDO().setBmiRating("不合格").setBmiScore(50D));
list.add(new EsFitnessTestRecordDO().setBmiRating("不合格").setBmiScore(40D));
list.add(new EsFitnessTestRecordDO().setBmiRating("不合格").setBmiScore(30D));
CollectionsUtils<EsFitnessTestRecordDO> ct = new CollectionsUtils(EsFitnessTestRecordDO.class);
//统计bmiRating字段 优秀、良好、合格、不合格的各自人数,bmiRating是传递的参数
Map<String, Long> map = ct.DynamicGroupListByFiled(list,"bmiRating");
//计算bmiScore字段的平均值,bmiScore是传递的动态参数
double bmiAverage = ct.getDynamicFieldAverage(list,"bmiScore");
}
调试bug图
打个断点慢慢调试 看看哪里错了
get方法的方法名和属性名定义看看有没有符合标准
加我qq帮你看看吧 1010729083
MethodHandle handle = lookup.findGetter(this.getT().getClass(), fieldName, String.class);
私有属性是会报错的 找不到的
换成这个就可以了 你试试
MethodHandle getterMethodHandle = lookup.findVirtual(this.getT().getClass(),
fieldName, MethodType.methodType(String.class));
你JDK的版本是不是有点低,不支持这个方法啊
findGetter获取getter方法,字段必须为public修饰,
findVirtual 获取一般方法。