BIGE_BIGGER 2018-10-31 02:43 采纳率: 0%
浏览 1434
已结题

java 动态依据不特定字段进行分组和统计

写了动态指定单个字段的分组,但是 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图
BUG

  • 写回答

3条回答 默认 最新

  • x060508 2018-10-31 07:29
    关注

    打个断点慢慢调试 看看哪里错了

    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));

    评论

报告相同问题?

悬赏问题

  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)