如何改进java中低效的for语句复制

如何改进java中低效的for语句复制,java,for-loop,performance,Java,For Loop,Performance,出于某种原因,我使用了一个重复的for语句,但不知何故我觉得效率低下。下面是我使用duplicated for语句的原因 我得到了“频道”数据,这是一个频道信息列表 频道信息为“Map”类型,包含许多元素 还有另一个表示程序信息的Map 我需要在每个频道中插入一个程序 源代码如下 public static void injectProgram2Channel ( List<Map<String, Object>> channelList, L

出于某种原因,我使用了一个重复的for语句,但不知何故我觉得效率低下。下面是我使用duplicated for语句的原因

  • 我得到了“频道”数据,这是一个频道信息列表
  • 频道信息为“
    Map
    ”类型,包含许多元素
  • 还有另一个表示程序信息的
    Map
  • 我需要在每个频道中插入一个程序
源代码如下

public static void injectProgram2Channel (
            List<Map<String, Object>> channelList, List<Map<String, Object>> programList) throws Exception {
        for(Map<String, Object> channel : channelList){
            String serviceId = channel.get("serviceId").toString();
            ArrayList<Map<String, Object>> programsForChannel = new ArrayList<Map<String,Object>>();
            for(Map<String, Object> program : programList){
                if(serviceId.equals(program.get("serviceId").toString())){
                    programsForChannel.add(program);
                }
            }
            channel.put("programs", programsForChannel);
        }
    }
publicstaticvoidinjectprogram2channel(
List channelList,List programList)引发异常{
用于(映射频道:频道列表){
字符串serviceId=channel.get(“serviceId”).toString();
ArrayList programsForChannel=新的ArrayList();
用于(映射程序:程序列表){
if(serviceId.equals(program.get(“serviceId”).toString()){
programsForChannel.add(程序);
}
}
频道播放(“节目”,节目频道);
}
}
我不想迭代所有列表,因为每个列表都有许多元素。如何提高其性能

  • 频道列表有大约500个元素
  • 程序列表包含大约2000个元素

(我需要不使用重复语句的解决方案)

你需要问自己一个问题:它有多快有关系吗。如果没有,就不要让代码变得更复杂。“过早优化是万恶之源”

一旦您确认性能是相关的,尝试创建一个基准,例如使用JMH,并在适当的地方开始优化

Channel List has around 500 Elements
Program List has around 2000 Elements

在现实世界的应用中,这些都非常小。如果只有两个嵌套的for循环用于该数量的数据,则不必担心。

正如所暗示的,在您的情况下,一个可能有意义或可能没有意义的选项是只需将程序按serviceId分组到一个新的
映射中,并在需要时查找程序

public static Map<String, List<Map<String, Object>>> buildProgramList (
        List<Map<String, Object>> programList) throws Exception {

    Map<String, List<Map<String, Object>>> programsByServiceId = new HashMap<>();

    for(Map<String, Object> program : programList){
        String serviceId = program.get("serviceId").toString();
        if(programsByServiceId.containsKey(serviceId)){
            programsByServiceId.get(serviceId).add(program);
        } else {
            programsByServiceId.put(serviceId,
                    new ArrayList<Map<String, Object>>(){{
                add(program);
            }});
        }
    }
    return programsByServiceId;
}
这将推迟前期成本并将其分摊

当这可能有意义的时候。如果有某些频道比其他频道更频繁地查找其节目列表


当这没有意义的时候。所有频道被要求立即或很快提供其节目列表。(例如,如果您只是要序列化所有频道及其程序)

你说得对。有一种方法可以通过一次遍历所有程序来实现这一点。我就到此为止,但请随意提出其他问题。我不想让你跳过自己弄明白的乐趣:)你是在建议跳过某些元素吗?除非要更改方法的功能,否则必须遍历
映射中的每个值。你需要一个
映射。
@Human这里没有“迭代”映射中的每个值。虽然我同意这一点,但注意你的代码如何在不使其变得更复杂的情况下更高效并没有什么错。有时我们会变得过于复杂,需要回去清理。通常。我建议你看看他到底说了些什么,以及他说这话时在说些什么。本案不适用。答案显然是一个更好的数据结构,这将带来一个重大的改进,而不是一个小的改进,研究这一点没有错。大多数软件设计都是从数据结构开始的,这要视情况而定。我以性能调整/分布式和并发计算为生。在没有意义的地方尽早引入复杂性,只会混淆问题。所以,只要做最简单的事情就行了,除非你能证明它与性能相关。当某些东西确实需要快速时,例如我们正在开发的新Hazelcast引擎,从一些基本但快速的东西开始,然后慢慢添加功能,然后调整复杂的系统要容易得多。因此,在这里,您可以看到良好的数据结构、锁定/阻塞的数量、对象垃圾、内存访问模式等。但我不认为用户的问题属于这一类。如果我们团队中有人增加了没有基准支持或在生产中没有实际价值的复杂性,代码将被拒绝;你不想为你不用的东西负重。如果代码更改没有增加任何复杂性和清晰度,我完全可以将其添加到代码库中。暗示的方法一直都是有意义的,因为它是O(n)而不是O(n^2),如果这只是一个字符串,那么它就很小,但是当我将这两个列表结合起来时,它占用了超过200MB的空间。所以我有点担心会被扩展(例如,可以添加频道)。
List<Map<String, Object>> programs = programsByServiceId.get(channel.get("serviceId").toString());
if (channel.get("programs") == null) 
    channel.put("programs", programsByServiceId.get(channel.get("serviceId").toString());
return channel.get("programs");