精华内容
下载资源
问答
  • HashMap解决双层For循环效率问题

    千次阅读 2019-12-31 21:48:35
    测试10w条数据双层for循环耗时 import java.util.ArrayList; import java.util.List; /** * @author 954L * @create 2019/12/31 20:42 */ public class Main { public static void main(String[] args) {...

     

    业务场景中很经常类似的需求,对两个List相同的数据进行处理。例子如下:

    import lombok.Builder;
    import lombok.Data;
    import lombok.experimental.Tolerate;
    
    /**
     * @author 954L
     * @create 2019/12/31 20:42
     */
    @Data
    @Builder
    public class User {
    
        private String name;
    
        @Tolerate
        public User(){}
    
    }
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * @author 954L
     * @create 2019/12/31 20:42
     */
    public class Main {
    
        public static void main(String[] args) {
            User zs = User.builder().name("张三").build();
            User ls = User.builder().name("李四").build();
            List<User> list1 = Arrays.asList(zs);
            List<User> list2 = Arrays.asList(ls);
            for (User user1: list1){
                for (User user2 : list2){
                    if (user1.getName().equals(user2.getName())){
                        //TODO 执行业务逻辑
                        break;
                    }
                }
            }
        }
    }

    假设大数据量情况下上述执行代码list2则会出现很多不必要的循环,直到equals为止,假设使用map,直接getKey出相同的list2中的对象,则效率可以大大提升!

     

    测试10w条数据双层for循环耗时

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author 954L
     * @create 2019/12/31 20:42
     */
    public class Main {
    
        public static void main(String[] args) {
            List<User> list1 = new ArrayList<>();
            for (int i = 0; i <= 100000; i++){
                list1.add(User.builder().name("张三" + i).build());
            }
            List<User> list2 = new ArrayList<>(list1);
            long startTime = System.currentTimeMillis();
            for (User user1: list1){
                for (User user2 : list2){
                    if (user1.getName().equals(user2.getName())){
                        //TODO 执行业务逻辑
                        break;
                    }
                }
            }
            System.out.println(System.currentTimeMillis() - startTime);
        }
    }

     

    测试HashMap耗时时间

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.function.Function;
    import java.util.stream.Collectors;
    
    /**
     * @author 954L
     * @create 2019/12/31 20:42
     */
    public class Main {
    
        public static void main(String[] args) {
            List<User> list1 = new ArrayList<>();
            for (int i = 0; i <= 100000; i++){
                list1.add(User.builder().name("张三" + i).build());
            }
            List<User> list2 = new ArrayList<>(list1);
            Map<String, User> list2Map = list2.stream()
                    .collect(Collectors.toMap(User::getName, Function.identity()));
            long startTime = System.currentTimeMillis();
            for (User user1: list1){
                User user = list2Map.get(user1.getName());
                if (user != null){
                    //TODO 执行业务逻辑
                }
            }
            System.out.println(System.currentTimeMillis() - startTime);
        }
    }

     

    测试结果一目了然了。

    but!数据量小的时候还是建议用list,差别不大。毕竟相同大小map占用的内存空间比list大

     

     

    对你有帮助的话,右上角给个赞呗~

     

     

     

     

     

     

    展开全文
  • 解决双重for循环效率问题题目说明题解 题目说明 当拥有2个表时,订单表和物品表 时,订单表(客户名称,订单ID)和物品表(订单ID,物品名称)一个客户可以购买多个物品,但是他们的订单ID是唯一的,数据库中数据以...

    解决双重for循环效率问题

    题目说明

    当拥有2个表时,订单表物品表 时,订单表(客户名称,订单ID)和物品表(订单ID,物品名称)一个客户可以购买多个物品,但是他们的订单ID是唯一的,数据库中数据以JSON字符串的形式传给你。

    订单表

    订单ID客户名称
    A1
    B2
    C3

    物品表

    订单ID物品名称
    A1
    B2
    C3

    请输出购买最多商品的人?购买最少商品的人?和平均一个人购买多少商品。

    题解

    1.解决思路,使用映射关系,提取出关键信息进行两表关联。
    客户名称 ↔ 订单ID
    订单ID ↔ 物品名称
    2.使得 订单ID作为唯一性属性进行映射对应。
    3.使用Map集合类型代替双重循环提高效率

    	/**
    	* 提供String orderJSON = “”; 存放订单JSON
    	* 提供String commodityJSON = “”; 存放商品JSON
    	*/
    	Map<String,String> orderMap = new HashMap();
    	Map<String,Integer> commodity = new HashMap();
    
    	JSONArray orderJsonArray = JSON.parseArray(orderJSON);
    	for(int i = 0;i<orderJsonArray .size();i++){
    		String orderStr = orderJsonArray.getString(i);
    		JSONObject jsonObject = JSONArray.parseObject(orderStr);
    		String customerName = jsonObject.getString("CustomerName");
    		String orderID = jsonObject.getString("OrderID");
    		orderMap.put(customerName,orderID);
    	}
    
    	JSONArray commodityJsonArray = JSON.parseArray(commodityJSON);
    	for(int i = 0;i<commodityJsonArray .size();i++){
    		String commodityStr = commodityJsonArray.getString(i);
    		JSONObject jsonObject = JSONArryay.parseObject(commodityStr);
    		String orderID = jsonObject.getString("OrderID");
    		String commodityName = jsonObject.getString("CommodityName");
    		if(commodity.get(orderID)==null){
    			commodity.put(orderID,1);
    		}else{
    			commodity.put(orderID,commodity.get(orderID)+1);
    		}
    	}
    
    	String maxStr = "";
    	String minStr = "";
    	int sum = 0;
    	int max = 0;
    	int min = commodity.size()/orderMap.size();
    	Iterator<Map.Entry<String, Integer>> iterator = commodity.entrySet().iterator();
    	while (iterator.hasNext()) {
    		Map.Entry<String, Integer> entry = iterator.next();
    		//System.out.println(entry.getKey() + "  " + entry.getValue());
    		sum += entry.getValue();
    		if(entry.getValue()>max()){
    			max = entry.getValue();
    			maxStr = orderMap.get(entry.getKey());
    		}
    		if(entry.getValue()<=min()){
    			min = entry.getValue();
    			minStr = orderMap.get(entry.getKey());
    		}
    	}
    	System.out.println("平均一个用户买物品数为 : "+sum/commodity.size());
    	System.out.println("购买最多的客户是 : "+maxStr+" 购买数量为:"+max);
    	System.out.println("购买最少的客户是 : "+minStr+" 购买数量为:"+min);
    	
    
    展开全文
  • 转自csdn ... 双重循环语句的书写,是有讲究的。不同的书写方式,效率会大不一样。有如下代码模块: typename tArray[20][600]; uint32 uIdxI = 0; //uint32 is short for unsigned int uint32 u...

    转自csdn

    双重循环语句的书写,是有讲究的。不同的书写方式,效率会大不一样。有如下代码模块:

    typename tArray[20][600];

    uint32 uIdxI = 0; //uint32 is short for unsigned int

    uint32 uIdxJ = 0;

    for (uIdxI = 0; uIdxI < 20; uIdxI++)

    {

    for (uIdxJ = 0; uIdxJ < 600; uIdxJ++)

    {

    tArray[uIdxI][uIdxJ] = ...; //assign value

    }//for, uIdxJ

    }//for, uIdxI

    对于以行优先存储方式的计算机来说,上述双重循环的运行效率最高。

    首先,现代的CPU的体系架构大多都用了预测分支技术,如果双重循环中外循环次数为nNumA,内循环次数为nNumB,则总体上预测失败次数为2 * nNumA + 2,在保证运行结果无误的前提下要保证外循环次数比内循环次数小。

    其次,现代的计算机体系的存储技术至少都用了局部存储思想,即CPU提取内存的一个位置的数据放到cache中的同时,也会把其附近的数据也提取到cache中,如果内存以行优先存储方式,则提取tArray[0][0]位置的数据的同时,则也会顺便把"tArray[0][1], tArray[0][2], tArray[0][3], tArray[0][4]..."等数据提取出来。

    上面提到了两个原理,其中第二个原理要比第一个原理重要,因为“CPU访问cache的速度要远高于访问内存的速度,一般CPU访问SRAM的速度比访问DRAM快1000倍”,分支预测失败顶多是对指令进行调整,而指令本身就是CPU所有,无需访问速度,但是数据则是在内存中,速度就很慢了。

    所以,如果操作系统对数组的存储方式是以列优先存储方式安排的,则上述代码中内循环应该放到外面去。

    转载于:https://my.oschina.net/u/201624/blog/1582063

    展开全文
  • 首先先来一个案例简单模拟一下: List<String> wifes = new ArrayList(); List<String> husbands= new ArrayList(); for(int i=0;... wifes.add(new Wife(i, i+"的妻子", "000"+i));...这种效率天差地别。  

    首先先来一个案例简单模拟一下:

    List<String> wifes = new ArrayList<String>();
    List<String> husbands= new ArrayList<String>();
    for(int i=0;i<8000;i++){
          wifes.add(new Wife(i, i+"的妻子", "000"+i));
    }
    for(int i=0;i<8000;i++){
          husbands.add(new Husband(i, "我是"+i, "000"+i));
    }
    
    //现在需要让妻子和丈夫进行配对组成一个家庭,按照familyId进行配对
    在1.8之前你会这么写:
    for(int i=0;i<wifes.size();i++){
            System.out.println("i:"+i);
        for(int j=0;j<husbands.size();j++){
            System.out.println("j:"+j);
              if(妻子的familyid==丈夫的familyid){
                    System.out.println("匹配成功:"+i+":"+j);
              }
        }
    }
    已8000*8000的两个集合进行配对。那就要循环8000*8000次。按20s循环一轮。需要20*8000秒

    如果按照jdk1.8的lamada表达式进行匹配的话。这个测试结果是ms级别的

    // 将list转为Map,这里key一定要为唯一值,map(familyId,wife对象)
    Map<String, Wife> wifeMap = wife.stream().collect(
            Collectors.toMap(w -> w.getFamilyId(),
                    w -> w));
    // 匹配家庭
    families = husband.stream().map(h -> {
        //从wifeMap里面根据husband的familyId去匹配。匹配上后组装成家庭对象然后放入集合。最后生成新的家庭集合
        return toFamily(wifeMap.get(h.getFamilyId()), h);
    }).collect(Collectors.toList());

    这是个测试案例:亲测如下:

    package com.nuanshui.frms.report.manage;
    
    
    import com.google.common.collect.Lists;
    import org.junit.Test;
    
    import java.math.BigDecimal;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    
    /**
     * Author:
     * Date: 2016/11/23.
     * Time: 18:17
     */
    public class TestFamily {
        @Test
        public void familyTest() {
            List<Wife> wife = Lists.newArrayList();
            List<Husband> husband = Lists.newArrayList();
            for(int i=0;i<8000;i++){
                wife.add(new Wife(i, i+"的妻子", "000"+i));
            }
    
            for(int i=0;i<8000;i++){
                husband.add(new Husband(i, "我是"+i, "000"+i));
            }
            Long startTime =System.currentTimeMillis();
            System.out.println("当前时间:"+startTime);
            List<Family> families = Lists.newArrayList();
            // 将list转为Map,这里key一定要为唯一值
            Map<String, Wife> wifeMap = wife.stream().collect(
                    Collectors.toMap(w -> w.getFamilyId(),
                            w -> w));
            // 匹配家庭
            families = husband.stream().map(h -> {
                return toFamily(wifeMap.get(h.getFamilyId()), h);
            }).collect(Collectors.toList());
            /*for(int i=0;i<wife.size();i++){
                System.out.println("i:"+i);
                for(int j=0;j<husband.size();j++){
                    System.out.println("j:"+j);
                    if(wife.get(i).getFamilyId().equals(husband.get(j).getFamilyId())){
                        System.out.println("匹配成功:"+i+":"+j);
                    }
                }
            }*/
            System.out.println("循环完成");
            families.stream().forEach(family -> {
                System.out.println("家庭ID:" + family.getFamilyId() + ",丈夫:" + family.getHusbandName() + ",妻子:" + family.getWifeName());
            });
            Long endTime =System.currentTimeMillis();
            System.out.println("结束时间:"+endTime);
            System.out.println("------------耗时:---------"+(endTime-startTime)+"ms");
        }
    
        private Family toFamily(Wife wife, Husband husband) {
            Family family = new Family();
            family.setFamilyId(wife.getFamilyId());
            family.setHusbandName(husband.getHusbandName());
            family.setWifeName(wife.getWifeName());
            return family;
        }
    
        @Test
        public void test1(){
            //String.valueOf()
            BigDecimal c = new BigDecimal(651000);
            BigDecimal d = new BigDecimal(312);
            BigDecimal num3 = c.divide(d,10,BigDecimal.ROUND_HALF_DOWN);
            System.out.println(num3);
            BigDecimal b = (new BigDecimal(651000).divide(new BigDecimal(312)).setScale(1, BigDecimal.ROUND_HALF_UP));
            System.out.println(b);
    
        }
    }
    
    

    结果只要252ms;

    这种效率天差地别。

     

    展开全文
  • 使用Map优化双层for循环 ...1.双层for循环使用场景 ...通常情况下,我们对于数据量比较多的时候,如果使用的双层for,会大大降低程序运行效率,对于数据量相对较少,使用双层for嵌套,是察觉不到什么效果的。
  • 1-1、for / while 最普通的循环 效率最高 兼容ie6 tips:for循环更适用于循环的开始和结束已知,循环次数固定的场合;while循环更适合于条件不确定的场合 1-2、for in 兼容ie6,效率最差(效率可看最下面的对比) ...
  • 两层嵌套for循环效率比较

    万次阅读 2013-11-05 23:41:21
    正常情况下,次数多的循环放在内层,会减少cache更新数据的次数,当离开内层循环的时候会恢复外层的计数器,外层循环次数越少,恢复计数器的次数越少,效率较高,由此看来情况二更加高效。 从cpu指令执行机制上来...
  • 两种方案优化实际开发中的双层for循环语句 附代码和实例 现有如下需求,需在订单信息类中根据用户信息类的userId匹配到对应的信息并输出商品skuId。 先给出实体类:用户信息类UserInfo和订单信息类OrderInfo。用户...
  • console.time(); var sum = 0; for(var i = 0; i < 2; i++) { for(var j = 0; j < 5000; j++) { sum += i * j; } } console.timeEnd(); console.time(); var sum = 0; for(var i = 0;......
  • for循环嵌套的运行效率

    千次阅读 2013-09-23 16:13:33
    9月22阿里笔试第三题遇到一个for循环运行效率的问题,一时蒙住了不知道该选什么,只是隐隐觉得两者的运行时间应当不同。 1). for ( i= 0; i  for (j =0; j  {expression;}   2). for ( i= 0; i  ...
  • List集合双层for循环的优化

    千次阅读 2019-05-21 16:19:32
    3、双层for循环效率极低,导致接口直接崩溃。时间复杂度(o(n2)) List<GradeInfo> list = new ArrayList(); // penVersionInfos(8万) for (PenVersionInfo penVersionInfo : penVersionInfos) { // List(16...
  • 双重循环优化,提高运行效率

    千次阅读 2018-09-19 16:28:38
    循环次数较少的时候for循环一般不会影响运行效率,但一旦循环次数较多,成千上万的时候,循环次数越多,效率就越慢,最近在做一程序的时候要解决优化问题,反复查看只有优化双重for循环才能提高效率。事实证明,优化...
  • 有两张表A、B。 A有500条记录,B有500乃至更多条,查询A表所有记录封装成List; 现根据A表的ID查询B表中对应的记录,那么 List<A> listA = getObjects(A.class);... for(A a : listA){/*...这两种方式哪个效率
  • 又回想起了当初写双重for循环的时候,以前看过相关文章,说是外小内大性能会比外大内小性能好,几乎99%的文章都是这么说的。 那么现在2020年这个结论还对吗,自己用jdk1.8试了试,例子的话就直接搬 @云海天教程网 ...
  • For循环效率

    2017-06-09 17:09:08
    for循环效率
  • 关于多层for循环迭代的效率优化问题 今天笔试的时候遇到这么一道题目 说有上面这么循环嵌套 ,问怎么优化 并说明原因。  for(int i = 0 ; i < 1000 ;i++){  for(int j = 0; i < ...
  • 前情提要:python在处理高时间复杂度的双重for循环时候效率低,而多线程又不适合于计算密集的任务提速。昨天睡之前让电脑自己运行17000*17000的计算,结果跑了19000秒。 因此尝试寻求为python提速的解决方案。在那...
  • 两重for循环效率对比

    千次阅读 2016-06-08 09:18:05
    int a[n][m] for(int i=0;i;i++){ for(int j=0;j;j++){ // a[i][j] } }for(int j=0;j;j++){ for(int i=0;i;i++){ ...}以上两个循环效率谁比较高: 对于现代数组来说,都是行存储优先:a[0][0]
  • 双层for循环用java中的stream流来实现

    千次阅读 2019-05-28 11:05:00
    //双重for循环for (int i = 0; i < fusRecomConfigDOList.size(); i++) { for (int j = 0; j < fusRecomConfigDOS.size(); j++) { if(fusRecomConfigDOList.get(i).getSceneCode().equ...
  • 关于二维数组循环效率问题

    千次阅读 2017-06-17 16:44:22
    假设有一n×m的二维数组,遍历其中每个元素时应该将n、m中大的放到内部的循环,减少变量的稀释次数,提高循环效率。举个例子: $count = 0; $startsmall = microtime(); for($i=0;$i100;$i++){ for($j=0...
  • 入门教程之列表渲染多层嵌套循环,目前官方的文档里,主要是一维数组列表渲染的案例,还是比较简单单一,给刚入门的童鞋还是无从入手的感觉。 &lt;view wx:for="{{items}}"&gt; {{index}}: {{...
  • 问题产生的背景是:数据库中有一字段 errorlist 内容为(举例):1,2,3,4... ...17-47更新(其实外侧还有循环导出十条 最外侧foreach 就是十次,最多一次导出一百条) 请教各位大神,我该如何优化?
  • 首先先来一个案例简单模拟一下: List<String> wifes = new ArrayList<String>(); List<String> husbands= new ArrayList<String>... wifes.add(new Wife(i, i+"的妻子", "000"+i));...
  • 充分利用循环可以提高程序的开发和执行效率,但是如果不注重循环中的算法很容易导致程序的死循环,那将是程序的死穴。所以在循环体中要对可能出现的特殊情况使用break语句中断循环。 public class BreakCyc { ...
  • // 双重循环 foreach($VW_SHANGPIN_FJSX as $k=>$v){ foreach($SHANGPIN as $ke=>$va){ if($v['spdm']==$ke['spdm']){ $VW_SHANGPIN_FJSX[$k]['zjf']=$SHANGPIN[$ke]['zjf']; $VW_SHANGPIN_FJSX[$k]['bzjj...
  • 在以上的SQL中,使用了双层循环,分别对不同的PBT_OPStationID和PBT_StepID进行计算。 结果 执行后,结果如下所示: PBT_ID PBT_ProductID PBT_OPStationID PBT_BoltID PBT_StepID PBT_...
  • [img=https://img-bbs.csdn.net/upload/201309/23/1379926743_886766.jpg][/img] [size=16px][color=#FF0000]本人的测试结果[/color][/size] [img=... 望能探讨一二
  • 当我们有两个List集合时,一个List集合中的People只有部分属性,另一个List集合中的People有另一部分属性,使用嵌套for循环进行比较拼接的效率是非常慢的,解决的办法就是使用HashMap来进行拼接。下面上代码来进行一...
  • 两步优化: ...2/数据处理确实无法减少嵌套,我采用了for循环来替代map,forEach,虽然降低了代码的可读性,但是这里因为数据量比较大,两层循环的原因,确实能有效节约时间。 优化前: 优化后: ...
  • Scala中的嵌套循环

    2020-07-30 17:00:35
    Scala中的嵌套循环 (Nested loop in Scala) In programming, a nested loop is used in initializing or iterate multi-dimensional array or to print patterns. Scala provides an efficient method to use nested...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,775
精华内容 1,510
关键字:

双层循环效率