如何在迭代时更新bean

时间:2015-03-26 11:23:22

标签: java list guava

我正在尝试更新bean的属性(如果它满足条件),同时迭代它的列表。为了提高性能,我使用Lists.transform

private void populate(final WorkFlowDataBean workFlowDataBean, final List<ApplicationDataBean> items) {
        Lists.transform(items, new Function<ApplicationDataBean, ApplicationDataBean>() {
            @Override
            public ApplicationDataBean apply(ApplicationDataBean input) {
                if (String.valueOf(workFlowDataBean.getId().intValue()).equalsIgnoreCase(String.valueOf(input.getWorkflowId().intValue()))) {
                    input.setWorkflowName(workFlowDataBean.getName());
                    input.setWorkflowVersion(workFlowDataBean.getVersion());
                    logger.info("---finally----");
                }
                logger.info(String.valueOf(workFlowDataBean.getId().intValue()) + "===" + String.valueOf(input.getWorkflowId().intValue()));
                return input;
            }
        });

    }

我不能使用foreach循环,因为它会减慢我的应用程序。

3 个答案:

答案 0 :(得分:3)

&#34;我不能使用foreach循环,因为它会减慢我的应用程序&#34;这里错了。尝试使用Lists.transform根本不会对你有所帮助,因为A)它没有做你认为它做的事情,B)它不是你做正确事情的正确方法。重新尝试(for-each循环)和C)你必须迭代List返回的Lists.transform,这不会比for-each循环更快。您似乎认为它的速度更快,因为您的代码实际上并没有做任何事情

如果你真的想让这个更快,你可能想要考虑并行操作。

答案 1 :(得分:2)

Lists.transform()实际上会返回一个延迟计算的列表视图,这意味着apply()中的所有内容只会在您开始迭代转换后的集合时发生。因此,您无法以现在使用该方法的方式使用该方法,因为如果您未使用转换后的列表,apply()永远不会被调用。

要解决此问题,您可以尝试根据转换的集合创建一个新列表(您也会丢弃):

Lists.newArrayList(Lists.transform(
    /*Your transformation code*/
));

更好的长期解决方案是重新考虑整体方法。也就是说,您应该只在方法中使用for-each循环,而不是将代码包装到函数中。在这种情况下,正常的命令式代码将更易于阅读并且性能也更好。

答案 2 :(得分:1)

正如其他人所说,返回的List不是实际的转换列表,而是原始List的视图,当稍后迭代时,它将应用转换到每个元素。

关于错误,您必须返回转换后的列表。这就是您的代码无效的原因:

private List<ApplicationDataBean> populate(final WorkFlowDataBean workFlowDataBean, final List<ApplicationDataBean> items) {
    return Lists.transform(items, new Function<ApplicationDataBean, ApplicationDataBean>() {
        @Override
        public ApplicationDataBean apply(ApplicationDataBean input) {
            if (String.valueOf(workFlowDataBean.getId().intValue()).equalsIgnoreCase(
                String.valueOf(input.getWorkflowId().intValue()))) {
                input.setWorkflowName(workFlowDataBean.getName());
                input.setWorkflowVersion(workFlowDataBean.getVersion());
                logger.info("---finally----");
            }
            logger.info(String.valueOf(workFlowDataBean.getId().intValue()) + "==="
                + String.valueOf(input.getWorkflowId().intValue()));
            return input;
        }
    });
}

然后,调用此方法并迭代返回的列表:

List<ApplicationDataBean> filteredTransformedList = populate(workFlowDataBean, items);

for (ApplicationDataBean bean : filteredTransformedList) {
    // do useful things with every filtered and transformed bean
}

关于使用命令式和功能性方法,只需使用您认为最好的方法。这种伪功能方法的优点是它可以懒惰地应用,即当最终迭代返回的列表时。但是,您应该注意,当您直接修改ApplicationDataBean input元素时,原始列表中的元素也会被修改。