BIGE_BIGGER 2018-10-30 10:25 采纳率: 0%
浏览 1006
已结题

java 统计集合中对象的不特定字段的平均值

动态统计某字段

图片说明

 private RecordLevelModel getRecordLevelModel(Map.Entry<Integer, List<EsFitnessTestRecordDO>> entry, List<EsFitnessTestRecordDO> projectAndSexList) {
        RecordLevelModel bmiMaleModel = new RecordLevelModel().setGradeNumber(entry.getKey());
        Integer bmiUrbanMaleTotal = projectAndSexList.size();
        Map<String,Long> bmiMaleMap =  projectAndSexList.stream().collect(
                Collectors.groupingBy(EsFitnessTestRecordDO::getBmiRating,Collectors.counting()));
        for(Map.Entry<String,Long> entry1 : bmiMaleMap.entrySet())
        {
            LevelAndRegionModel levelAndRegionModel = new LevelAndRegionModel();
            double rate = entry1.getValue()/bmiUrbanMaleTotal;
            levelAndRegionModel.setLevelName(entry1.getKey()).setRate(rate).setTotal(Integer.parseInt(entry1.getValue().toString()));
            bmiMaleModel.getLevelModelList().add(levelAndRegionModel);
        }
        String projectName = "";
        Class<EsFitnessTestRecordDO> clz = EsFitnessTestRecordDO.class;
        try {
            String methodName = "get"+projectName;
            Method method = EsFitnessTestRecordDO.class.getMethod(methodName);
            double ave =  projectAndSexList.stream().mapToDouble(method).average().average().getAsDouble();
            double average = projectAndSexList.stream().mapToDouble(EsFitnessTestRecordDO::getBmi).average().getAsDouble();
        }catch (NoSuchMethodException e){
        }
        return bmiMaleModel;
    }

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

  • 写回答

1条回答 默认 最新

  • threenewbee 2018-10-30 10:37
    关注

    你光贴图片,没办法在上面给你改,但是,你可以把getBmiRating那里换成反射获取某个列的值。

    以前用C#写过类似的程序,你看看是不是要这个效果:
    https://ask.csdn.net/questions/703207

    这里有一个java stream动态分组的代码:

    private static Map<List<String>, List<MyClass>> groupListBy(List<MyClass> data, String[] groupByFieldNames) {
        final MethodHandles.Lookup lookup = MethodHandles.lookup();
        List<MethodHandle> handles = 
            Arrays.stream(groupByFieldNames)
                  .map(field -> {
                      try {
                          return lookup.findGetter(MyClass.class, field, String.class);
                      } catch (Exception e) {
                          throw new RuntimeException(e);
                      }
                  }).collect(toList());
        return data.stream().collect(groupingBy(
                d -> handles.stream()
                            .map(handle -> {
                                try {
                                    return (String) handle.invokeExact(d);
                                } catch (Throwable e) {
                                    throw new RuntimeException(e);
                                }
                            }).collect(toList())
            ));
    }
    

    同样的思路做动态取平均值也是一样的。

    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)