两个for循环嵌套优化

背景

前段时间在公众号中看到一篇技术文章,关于for循环嵌套的优化方法,感觉很实用(比较原来自己遇到过),下面分享给大家,同时加深理解,欢迎讨论。
数量较小时,嵌套for循环运行基本没什么影响,如果数据量较大运行时间明显变长,毕竟复杂度是O(n),数据量大或者循环嵌套过多,代码执行耗时会很恐怖。

优化方式

优化方式一

在for循环中使用break,减少执行次数,从而减少耗时,当然也是针对数据量不大,嵌套少,有一定的判断条件。
如下代码

public static List<User> getUserTestList() {
    List<User> users = new ArrayList<>();
    for (int i = 1; i <= 50000; i++) {
        User user = new User();
        user.setName(UUID.randomUUID().toString());
        user.setUserId((long) i);
        users.add(user);
    }
    return users;
}

public static List<UserMemo> getUserMemoTestList() {
    List<UserMemo> userMemos = new ArrayList<>();
    for (int i = 30000; i >= 1; i--) {
        UserMemo userMemo = new UserMemo();
        userMemo.setContent(UUID.randomUUID().toString());
        userMemo.setUserId((long) i);
        userMemos.add(userMemo);
    }
    return userMemos;
}
public static void main(String[] args) {
    List<User> userTestList = getUserTestList();
    List<UserMemo> userMemoTestList = getUserMemoTestList();


    StopWatch stopWatch = new StopWatch();
    stopWatch.start();

    for (User user : userTestList) {
        Long userId = user.getUserId();
        for (UserMemo userMemo : userMemoTestList) {
            if (userId.equals(userMemo.getUserId())) {
                String content = userMemo.getContent();
                System.out.println("模拟数据content 业务处理......"+content);
                break;
            }
        }
    }


    stopWatch.stop();
    System.out.println("最终耗时"+stopWatch.getTotalTimeMillis());


}

耗时比两个for循环执行时间缩短一半以上。

优化方式二

使用map 去优化,map的取值效率 在多数的情况下是能维持接近 O(1) 的 ,数组加链表。
相当于拿到userId 想去开盲盒的时候, 根据userId 这个key hash完能直接找到数组里面的索引标记位, 如果底下没链表(有的话O(logN)),直接取出来就完事了。
示例代码如下:

public static void main(String[] args) {
    List<User> userTestList = getUserTestList();
    List<UserMemo> userMemoTestList = getUserMemoTestList();


    StopWatch stopWatch = new StopWatch();
    stopWatch.start();

    Map<Long, String> contentMap =
            userMemoTestList.stream().collect(Collectors.toMap(UserMemo::getUserId, UserMemo::getContent));

    for (User user : userTestList) {
        Long userId = user.getUserId();
        String content = contentMap.get(userId);

        if (StringUtils.hasLength(content)) {
            System.out.println("模拟数据content 业务处理......" + content);
        }

    }

    stopWatch.stop();
    System.out.println("最终耗时" + stopWatch.getTotalTimeMillis());


}

运行结果耗时不到1秒。

特别感谢“java基基”、“芋道源码”公众号提供的相关文章,感谢分享资料的作者。

你可能感兴趣的:(for循环,循环优化)