Java高效实现python切片操作

本文探讨如何在Java中模仿Python数组切片操作,包括使用工具类方法、处理大数据切片和利用并行流提高效率。通过实例展示了`Arrays.copyOfRange`、`substring`和`subList`等方法,并对比了单线程与多线程计算性能。
摘要由CSDN通过智能技术生成


1 问题描述

在python中,我们可以执行以下操作,但是需要java实现

 array = [0,1,2,3,4,5,6,7,8,9,10]
 new_array= array[::3]
 print(new_array)

[0,3,6,9]

2 解决方案

2.1 工具类方法切割

Array 数组

int[] test_int = new int[] { 1, 2, 3, 4, 5};
test_int = Arrays.copyOfRange(test_int, 1, 4);
System.out.println(Arrays.toString(test_int));

执行结果:
img

使用的是 Arrays里面的copyOfRange(被切片的数组, begin_index, end_index)

这里的 begin_index, end_index 对应 Python中 [begin_index: end_index]

遵循 左闭右开 之后的方法也都是遵循这个不再重复

String 字符串

String test_string = "12345";
test_string = test_string.substring(1, 4);
System.out.println(test_string);

执行结果:
img

在这三个类型中 只有数组需要调用Arrays类中的方法,在字符串list 均是调用了实例化的方法,直接在实例化的后面 "."一下 加上字母 “sub”就会出先对应的方法

.substring(begin_index, end_index)

List 数组

ArrayList<Integer> test_list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
ArrayList<Integer> test_list_2 = new ArrayList<>(test_list.subList(1, 4));
System.out.println(test_list_2);

执行结果:
img

list的方法也是在实例化的对象上点一下出现subxxx的字样,那就是切片操作了

.subList(begin_index, end_index)

就是要把切片过后的list存放在另外一个list对象中会比较麻烦, 就和初始化list一样麻烦。。。

当然你如果没有存放切片之后的list的要求你也可以直接打印

System.out.println(test_list.subList(1, 4));

结果都是一样的
img

2.2 数据量很大需要切片

上面方法对于频繁的切片并且数组量很大就略显吃力了

在这里插入图片描述

这里数组要进行不断的复制很吃内存,需要开辟新的数组对象接收,而下面是流直接对数组进行操作,效率提升很多

int [] a = new int [] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// filter out all indices that evenly divide 3
int [] sliceArr = IntStream.range(0, a.length).filter(i -> i % 3 == 0)
    .map(i -> a[i]).toArray();

System.out.println(Arrays.toString(sliceArr));

在这里插入图片描述

在这里插入图片描述

2.3 并行流进行切片

最后如果还要提供计算速度的话采用并行流进行计算,是一种思路没有实践

性能测试

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class StreamParallelDemo {

    /** 总数 */
    private static int total = 100_000_000;

    public static void main(String[] args) {
        System.out.println(String.format("本计算机的核数:%d", Runtime.getRuntime().availableProcessors()));

        // 产生1000w个随机数(1 ~ 100),组成列表
        Random random = new Random();
        List<Integer> list = new ArrayList<>(total);

        for (int i = 0; i < total; i++) {
            list.add(random.nextInt(100));
        }

        long prevTime = getCurrentTime();
        list.stream().reduce((a, b) -> a + b).ifPresent(System.out::println);
        System.out.println(String.format("单线程计算耗时:%d", getCurrentTime() - prevTime));

        prevTime = getCurrentTime();
        // 只需要加上 .parallel() 就行了
        list.stream().parallel().reduce((a, b) -> a + b).ifPresent(System.out::println);
        System.out.println(String.format("多线程计算耗时:%d", getCurrentTime() - prevTime));

    }

    private static long getCurrentTime() {
        return System.currentTimeMillis();
    }
}

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵广陆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值