在Java中将数组拆分为较小的数组的最佳方法是什么?

3

在Java方法中将一个数组拆分为较小的数组,有哪种方法最好? 我想能够将任何大小的数组投入到takeReceipts(String[])中。

//Can handle any size array  
public void takeReceipts(String[] receipts){
//split array into smaller arrays, and then call handleReceipts(String[]) for every smaller array
}

//This method can only handle arrays with the size of 5 or less
private void handleReceipts(String[] receipts){
myNetworkRequest(receipts);
}

编辑:

看起来把数组复制到另一个数组里并不高效。做类似这样的改动会有用吗?

    public void takeReceipts(String[] receipts){

    int limit = 5;
    int numOfSmallerArrays = (receipts.length/limit)+(receipts.length%limit);
    int from = 0;
    int to = 4;
        for (int i = 0; i < numOfSmallerArrays; i++){
            List<String> subList = Arrays.asList(receipts).subList(from, to);
            from =+ limit;
            to =+ limit;
    }

}

看看我的答案,它可以处理这个。 - hasan
你计算 numOfSmallerArrays 的方法有误 - 应该是 int numOfSmallerArrays = ((receipts.length+limit-1)/limit);。你还需要添加一个检查 if (to >= receipts.length) to = receipts.length()-1; - Sergey Kalinichenko
我的解决方案使用 Math.min(i+5, receipts.length-1) 处理这个问题。 - hasan
第二,@dasblinkenlight 我应该在哪里添加那个if语句? - EGHDK
@EGHDK,您的表达式未正确计算较小数组的数量:例如,如果receipts.length199,而limit10,则您的表达式将产生28而不是正确的结果20。需要在循环结束时插入if以避免to的值超过限制。 - Sergey Kalinichenko
显示剩余6条评论
3个回答

4
你可以使用 Arrays.copyOfRange() 来实现:
int from = 0;
int to = 4;
String[] subArray = Arrays.copyOfRange(receipts, from, to)

1
System.arraycopy 不是更快吗? - royhowie
Arrays.copyOfRange() 在内部使用 System.arraycopy() - Eng.Fouad
我正在执行:Arrays.copyOfRange(receipts, from, to),其中from = 0,to = 2,但是我得到的数组只有receipts[0]和receipts[1]。为什么? - EGHDK
@EGHDK,你有看他链接的文档吗?“to - 要复制的范围的最终索引,不包括在内。(此索引可能位于数组之外。)” - royhowie
所以,from是包含的,而to是不包含的? - EGHDK

2

如果您愿意使用 List<String> 代替 String[] 数组,您可以以极其经济的方式进行分区:

List<String> subList = Arrays.asList(receipts).subList(from, to);

这种方法不会复制你的数组,而是提供了一个只读视图,查看原始收据数组。
static final int LIMIT = 10;

public static void process(List<String> small) {
    if (small.size() > LIMIT) {
        System.out.print("Array is too big: "+small.size());
        return;
    }
    for (String s : small) {
        System.out.print(s+" ");
    }
    System.out.println();
}

public static void processBig(String[] receipts) {
    int numChunks = ((receipts.length+LIMIT-1)/LIMIT);
    int from = 0;
    int to = LIMIT;
    List<String> bigList = Arrays.asList(receipts);
    for (int i = 0 ; i != numChunks ; i++) {
        List<String> subList = bigList.subList(from, to);
        process(subList);
        from += LIMIT;
        to += LIMIT;
        if (to >= receipts.length) {
            to = receipts.length;
        }
    }
}

演示.

采用这种方法的后果是,对原始数组元素所做的更改会通过视图“可见”,而且您无法以任何方式更改生成的subList


我该如何在 takeReceipts(String[] receipts) 方法中实现这个?请检查我的更新。谢谢。 - EGHDK

1
public void takeReceipts(String[] receipts){
    for (int i=0; i< receipts.length; i+=5)
        handleReceipts(Arrays.copyOfRange(receipts, i, Math.min(i+4, receipts.length-1)));
}

private void handleReceipts(String[] receipts){ 
}

或者

public void takeReceipts(String[] receipts){
    for (int i=0; i< receipts.length; i+=5)
        handleReceipts(Arrays.asList(receipts).subList(i, Math.min(i+4, receipts.length-1)));
}

private void handleReceipts(List<String> receipts){
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接