List或者Map等对象创建语句放在循环外和循环内的区别

本文介绍了一种在Java中使用List存储Map对象的方法,并详细解释了如何通过SQLQuery获取数据并将其转换为List中的Map对象。同时强调了对象引用的概念。

每一个对象创建的时候都会有一个ID,List对象在执行add方法的时候是将对象的引用放入List中。

如果把创建Map对象的语句放在外面,在将对象add到List中时,前后向List中add的对象都是同一个,

所以放在外面的时候最后List中的对象是同一个对象。

SQLQuery query = session.createSQLQuery(sb.toString());
List<Map<String,String>>attendanceRecordsList = new ArrayList<Map<String,String>>();
List <Object>list = query.list();
Iterator <Object>iter = list.iterator();
while(iter.hasNext()){
Object[] obj = (Object[])iter.next();
String departName = String.valueOf(obj[0]);//部门
String userName = String.valueOf(obj[1]);//姓名
String attendanceDateTime = String.valueOf(obj[2]);//签卡时间
String createDateTime = String.valueOf(obj[3]==null?"":obj[3]);//创建时间
String dataSource = String.valueOf(obj[4]==null?"":obj[4]);//数据来源
Map<String,String> map = new HashMap<String,String>();
map.put("departName", departName);
map.put("userName", userName);
map.put("attendanceDateTime", attendanceDateTime);
map.put("createDateTime", createDateTime);
map.put("dataSource", dataSource);
attendanceRecordsList.add(map);
}

转载于:https://www.cnblogs.com/damoblog/p/8191886.html

<think>好的,用户现在有一个需求,要将一个包含90万对象List转换成List<Map>,并且要求高效率。我需要仔细考虑这个问题,找出最优化的方法。 首先,我需要明确用户的具体需求。用户提到的“90万的list对象集合转list map集合”,可能是指将List中的每个对象转换为一个Map,其中每个Map的键值对对应原对象的属性。比如,一个User对象可能有id、name等属性,转换后每个User对象变成Map的键值对,如{"id":1, "name":"Alice"}。目标是将这个转换过程尽可能高效,减少时间资源消耗。 接下来,我需要分析可能影响效率的因素。处理90万的数据量,任何小的效率提升都会累积起来。主要考虑以下几个方面: 1. **初始容量设置**:ArrayList在扩容时会导致数组复制,影响性能。如果预先设置合适的初始容量,可以减少扩容次数。例如,假设原始List的大小是90万,那么新的List也应初始化为同样的大小,避免多次扩容。 2. **对象转换方式**:使用反射虽然灵活,但性能较差。如果用户能通过getter方法直接获取属性,或者直接访问字段,会更快。但需要看对象的结构是否允许。 3. **并行流处理**:Java 8的并行流可以利用多核处理器,加快处理速度。但需要考虑线程安全同步开销,如果每个元素的处理是独立的,并行流可能有效。 4. **避免不必要的操作**:例如,在循环创建不必要的对象或者重复计算,应该尽量减少。 接下来,我需要给出具体的实现方案。假设用户的对象有明确的getter方法,可以采用以下步骤: 1. **预先初始化List的大小**:使用ArrayList的构造函数指定初始容量,避免扩容。 2. **使用高效的遍历方式**:比如for循环比增强型for循环稍快,但差异不大。或者使用流式处理,尤其是并行流。 3. **优化单个对象的转换**:在转换每个对象Map时,尽可能直接调用getter方法,而不是用反射。例如,手动将每个属性put到Map中。 示例代码可能如下: ```java List<MyObject> originalList = ...; // 原始List,假设有90万元素 List<Map<String, Object>> resultList = new ArrayList<>(originalList.size()); for (MyObject obj : originalList) { Map<String, Object> map = new HashMap<>(); map.put("id", obj.getId()); map.put("name", obj.getName()); // 添加其他属性 resultList.add(map); } ``` 如果属性较多,手动编写每个put语句可能繁琐,但这是最高效的方式。如果属性很多,可以考虑使用反射,但需要缓存反射相关的元数据,比如Field或Method对象,避免每次循环都进行查找。 另一个优化点是使用更快的Map实现,比如提前指定HashMap的初始容量负载因子,减少resize次数。例如,如果每个Map有4个属性,可以初始化容量为(4/0.75 +1)=6,即new HashMap<>(6)。 如果考虑并行处理,可以使用并行流: ```java List<Map<String, Object>> resultList = originalList.parallelStream() .map(obj -> { Map<String, Object> map = new HashMap<>(); map.put("id", obj.getId()); map.put("name", obj.getName()); // 其他属性 return map; }) .collect(Collectors.toList()); ``` 但需要注意,并行流在数据量大时可能更高效,但需要测试实际效果,因为线程切换合并结果也会有开销。 另,可以考虑使用对象池或重用Map对象,但必须确保线程安全,这在并行流中可能不可行,因为每个线程处理自己的元素。 此,如果原始数据是只读的,可以考虑其他数据结构或更高效的序列化方式,但可能在当前问题中不适用。 可能的问题: - 原始对象的属性数量:如果属性很多,手动写put语句麻烦,如何解决? - 是否允许使用第三方库,如Apache Commons BeanUtils或Spring的BeanMap,但这些库可能使用反射,效率不如直接调用方法。 - 内存使用情况:90万Map对象会占用较多内存,可能需要考虑内存优化,比如使用更紧凑的数据结构或序列化。 最终,最有效的方法还是预先初始化List大小,直接调用getter方法,并尽可能减少每次循环中的开销。</think><< 将包含90万对象List高效转换为List<Map>,可以通过以下方法实现: 1. **预初始化集合容量** 使用`new ArrayList<>(initialCapacity)`预先指定List容量,避免动态扩容带来的性能损耗。 ```java List<MyObject> originalList = ...; // 原始数据 List<Map<String, Object>> resultList = new ArrayList<>(originalList.size()); ``` 2. **直接属性访问** 通过直接调用对象的getter方法填充Map,避免反射带来的性能损失: ```java for (MyObject obj : originalList) { Map<String, Object> map = new HashMap<>(4); // 根据属性数量初始化容量 map.put("id", obj.getId()); map.put("name", obj.getName()); // 其他属性... resultList.add(map); } ``` 3. **并行流加速** 使用Java 8并行流利用多核CPU(需确保操作是线程安全的): ```java List<Map<String, Object>> resultList = originalList.parallelStream() .map(obj -> { Map<String, Object> map = new HashMap<>(); map.put("id", obj.getId()); map.put("name", obj.getName()); // 其他属性... return map; }) .collect(Collectors.toList()); ``` **优化原理**: - **容量预分配**:ArrayList扩容需要复制数组,预分配可减少90万次潜在的数据拷贝。 - **避免反射**:直接调用getter方法比反射(如BeanUtils)快10-100倍。 - **并行处理**:并行流将任务分割到多个CPU核心,适合CPU密集型操作。 **注意事项**: - 如果对象属性较多,手动编写put语句可能冗长,但性能最优。 - 并行流可能因线程竞争导致性能下降,需实际测试验证效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值