【问题标题】:Need help in optmizing the following code需要帮助优化以下代码
【发布时间】:2017-02-04 07:51:14
【问题描述】:

我正在使用 google guava 库从提到的包中递归获取所有类,并遍历所有公共方法并获取它们的参数。然后将“mapOfpackageMethodParameters”传递给gson对象,这会给我json。

有什么方法可以通过使用 lambdas 或 java8 流 api 来优化两个最里面的 for 循环。还有其他建议吗??

String[] packagenames = { "com.example" };
LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, String>>> mapOfpackageMethodParameters = new LinkedHashMap<>();
for (String packagename : packagenames) {
    List<ClassInfo> clazzList = ClassPath.from(ClassLoader.getSystemClassLoader())
            .getTopLevelClassesRecursive(packagename).stream().filter(c -> c.getPackageName().endsWith("test"))
            .collect(Collectors.toList());
    for (ClassInfo class1 : clazzList) {
        List<Method> methodList = Arrays.asList(Class.forName(class1.getName()).getMethods());
        LinkedHashMap<String, LinkedHashMap<String, String>> methodMap = new LinkedHashMap<>();
        for (Method method : methodList) {
            List<Parameter> parameterList = Arrays.asList(method.getParameters());
            LinkedHashMap<String, String> parameterMap = parameterList.stream()
                    .collect(Collectors.toMap(param -> param.getName(), param -> param.getType().toString(),
                            (x, y) -> x, LinkedHashMap::new));
            methodMap.put(method.getName(), parameterMap);
        }
        mapOfpackageMethodParameters.put(class1.getName(), methodMap);
    }
}

这是预期并从上述代码生成的最终 json。

{
    "com.example.test.dummyclass": {
        "sampletest1": {
            "dummyargument1": "class java.lang.String",
            "dummyargument2": "class java.lang.String"
        },
        "sampletest2": {
            "dummyargument1": "class java.lang.String",
            "dummyargument2": "class java.lang.Integer"
        }
    }
}

【问题讨论】:

  • 你想优化这个性能还是优化这个从代码复杂性的角度来看?
  • 主要优化复杂度。顺便说一句,使用parallelStream可以提高性能吗??
  • 编写中介方法。您的代码几乎难以辨认,因为您在一个地方放了太多东西。如果您打算将所有这些作为 gson 对象返回,我强烈建议您编写需要返回的特定对象,例如 PackageJson、ClassJson、MethodJson。然后这些对象将由 Gson 自动转换。删除地图已经是降低复杂性的一大步,因为泛型较少,这会使整个内容难以辨认。
  • @OlivierGrégoire 感谢您的建议。但是我已经尝试过了,并且该代码花费了太多时间来生成具有相同输入的 json 文件。所以我不得不放弃它并改写成这个。它比我之前想到的解决方案性能更好。
  • @SuhailSullad 使用parallelStream() 通常会伤害而不是帮助性能。并行性的开销仅对 非常非常大 条数据或 非常非常大 操作才值得。这还不够大。

标签: java reflection lambda java-stream guava


【解决方案1】:

您可以将每个for..each 循环转换为一个流,该流收集到一个LinkedHashMap。使整个操作非常实用。

String[] packageNames = { "com.example" };
LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, String>>> mapOfpackageMethodParameters = Arrays
    .stream(packageNames)
    .flatMap(packageName -> ClassPath
        .from(ClassLoader.getSystemClassLoader())
        .getTopLevelClassesRecursive(packageName)
        .stream())
    .filter(classInfo -> classInfo.getPackageName().endsWith("test"))
    .map(ClassInfo::load)
    .collect(Collectors.toMap(
        Class::getName,
        clazz -> Arrays
            .stream(clazz.getMethods())
            .collect(Collectors.toMap(
                Method::getName,
                method -> Arrays
                    .stream(method.getParameters())
                    .collect(Collectors.toMap(
                        Parameter::getName,
                        param -> param.getType().toString(),
                        (x, y) -> x, LinkedHashMap::new)),
                (x, y) -> x, LinkedHashMap::new)),
        (x, y) -> x, LinkedHashMap::new));

【讨论】:

  • 很棒但不起作用“未处理的异常类型 IOException”。
  • @SuhailSullad 编译器错误指向代码的哪一部分?据我所知,我没有添加任何引发该异常的代码,因此问题也出在您的原始代码中。
  • 原始代码已处理IOException。当我尝试编译上述代码时,Eclipse 错误提示 ClassPath.from(ClassLoader.getSystemClassLoader()) has unhandled exception.
  • 我看不到它在您的原始代码中的处理位置。如果您需要帮助解决该错误,请查看this question。否则我已经给你答案了。
  • 奇怪的 Eclipse IDE 行为。无论如何,找出导致问题的原因并解决了它。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 2017-04-12
  • 2011-08-13
  • 2015-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多