java8 skip和limit学习使用
有时候需要对数据进行批处理,尤其是使用mybatis进行批量插入的时候。
skip+limit学习
1,skip(long n) 方法跳过前 n (非负)个元素,返回剩下的流,有可能为空流
2,limit(long maxSize): 方法截断其前个maxSize元素;若原流中包含的元素个数小于maxSize,那就获取其所有的元素;
skip
public static void main(String[] args) {skip();}// skip(long n) 方法跳过前 n (非负)个元素,返回剩下的流,有可能为空流。public static void skip() {List<String> names = Arrays.asList("ling", "lian", "yan", "feng", "yun", "wen", "tian", "lang", "xiu");String skipFirstName = names.stream().skip(0).findFirst().orElse("");System.out.println("skipFirstName: " + skipFirstName);String skipLastName = names.stream().skip(names.size() - 1).findFirst().orElse("");System.out.println("skipLastName: " + skipLastName);names = Collections.singletonList("yan");// 超出报错String penultName = names.stream().skip(names.size() - 2).findFirst().orElse("");System.out.println("reduce penultName: " + penultName);}
第三个超出,就报错了。
limit:
public static void main(String[] args) {limit();}// limit(long n): 方法截断其前个n元素;若原流中包含的元素个数小于n,那就获取其所有的元素;public static void limit() {List<String> names = Arrays.asList("ling", "lian", "yan", "feng", "yun", "wen", "tian", "lang", "xiu");List<String> limit1 = names.stream().limit(5).collect(Collectors.toList());System.out.println("inner size: " + limit1);List<String> limit2 = names.stream().limit(25).collect(Collectors.toList());System.out.println("over size: " + limit2);}
结果:
inner size: [ling, lian, yan, feng, yun]
over size: [ling, lian, yan, feng, yun, wen, tian, lang, xiu]
skip+limit批处理
public static void main(String args[]) {List<Integer> datas = new ArrayList<>();for (int i = 0; i < 26; i++) {datas.add(i);}skipData2(datas, 5);System.out.println("===========");skipData2(datas, 6);}public static void skipData1(List<Integer> datas, int maxSize){int dataSize = datas.size();// 向上取整
// int loop = dataSize / maxSize + (dataSize % maxSize != 0 ? 1 : 0);int loop =(int) Math.ceil(dataSize * NumberUtils.DOUBLE_ONE / maxSize);List<Integer> skipData;for (int i = 0; i < loop; i++) {skipData = ListUtils.emptyIfNull(datas).stream().skip(i * maxSize).limit(maxSize).collect(Collectors.toList());System.out.println(skipData);}}public static void skipData2(List<Integer> datas, int maxSize){List<Integer> skipData;for (int offset = 0, listSize = datas.size(); offset < listSize; offset += maxSize) {skipData = datas.stream().skip(offset).limit(maxSize).collect(Collectors.toList());System.out.println(skipData);}}
结果:
[0, 1, 2, 3, 4]
[5, 6, 7, 8, 9]
[10, 11, 12, 13, 14]
[15, 16, 17, 18, 19]
[20, 21, 22, 23, 24]
[25]
===========
[0, 1, 2, 3, 4, 5]
[6, 7, 8, 9, 10, 11]
[12, 13, 14, 15, 16, 17]
[18, 19, 20, 21, 22, 23]
[24, 25]
第一种更符合分页的那种习惯写法。
应用:
mybatis 使用foreach进行批量插入的时候,因为默认执行器类型为Simple,会为每个语句创建一个新的预处理语句,也就是创建一个PreparedStatement
对象。在我们的项目中,会不停地使用批量插入这个方法,而因为MyBatis对于含有的语句,无法采用缓存,那么在每次调用方法时,都会重新解析sql语句。而且PreparedStatement特别长,包含了很多占位符,对于占位符和参数的映射尤其耗时。
因此使用foreach进行插入,一次性插20~50行数量是比较合适的,时间消耗也能接受。 这时候就用到上面批处理数据了。
总结:
使用skip和limit适合对数据进行批处理。