如何在Java中迭代列表并每次获取10个元素

7
我有一个包含70个元素的列表。
例如: List<Long> dbList = new ArrayList<Long>(); dbList有70条记录。如果我将所有记录发送到MySql查询中,那么会花费很长时间。所以现在我想每次发送10个元素到数据库查询。因此,我需要按10的间隔迭代列表。如何做到这一点?这是避免使用IN时长时间等待的好方法吗? SQL查询
select model.boothId, model.panchayat.panchayatId
from Table1 model
where model.panchayat.panchayatId in(:locationValues)
  and model.publicationDate.publicationDateId in (:publicationDateIdsList)
  and model.constituency.id = :id group by model.panchayat.panchayatId

Thanks in advance...


2
你能展示一下你的SQL吗? - d'alar'cop
3
70个记录?很长时间?它们是什么?电影文件吗? - Strawberry
no no.Just 1,2,3,5,.....70 - PSR
@Dmitry 不,我需要一次使用结果。 - PSR
@Dmitry,有没有其他的解决方案适合我? - PSR
显示剩余6条评论
8个回答

21

ArrayList#subList 是一项非常高效的操作。您可以迭代大小为10的范围:

for (int i = 0; i < dbList.size(); i += 10) {
   List<Long> sub = dbList.subList(i, Math.min(dbList.size(),i+10)));
   ... query ...
}

如果我的列表只包含65个记录,那么我会得到任何异常吗?例如数组越界异常。 - PSR
Math.min 应该处理边缘情况。 - Marko Topolnik

2
如果您使用Eclipse Collections(以前称为GS Collections)并将dbList更改为MutableList或类似的对象,则可以编写以下代码:

MutableList<Long> dbList = ...;
RichIterable<RichIterable<Long>> chunks = dbList.chunk(10);

如果您无法更改dbList的返回类型,则可以将其包装在ListAdapter中。
RichIterable<RichIterable<Long>> chunks = ListAdapter.adapt(dbList).chunk(10);

注意:我是 Eclipse Collections 的提交者。

1
我希望Eclipse Collections能够取代JCL。我喜欢这个库!如果有一个只返回单个RichIterable的.take(10)就好了。 - Kenny Cason

1
你可以使用List接口中的subList方法,来分割你的列表。

0

这是一个简单的类,其中包含一个函数,用于返回从指定起始索引开始的列表中的10个元素。

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

public class TestTenElement {

public static void main(String[] args) {
    // Getting all the element list from DB -- Here Creating Sample List
    List<Long> myList = new ArrayList<Long>();

    // Dummy element list
    for (long i = 0; i < 51; i++) {
        myList.add(i);
    }

    // Calling function may be from different class
    System.out.println(getFiveElement(myList, 0)); // First Ten Element from StartIndex 0
    System.out.println(getFiveElement(myList, 10)); // Second Ten Element from StartIndex 5
    // .......
    System.out.println(getFiveElement(myList, 50)); // If Last Iteration Gives remaining elements
}

// print ten element from list from the start index specified
public static List<Long> getFiveElement(List<Long> myList, int startIndex) {
    List<Long> sub = new ArrayList<Long>();

    sub = myList.subList(startIndex, Math.min(myList.size(), startIndex + 10));
    return sub;

}
}

0

在纯Java代码中,这可能是可以完成的:

int parts = list.size()/10;

        for(int i=0; i<10; i++){
            for(int j=0; j<parts; j++){
                Long l = list.get(j + i*j);
                // l do sth;
            }
        }

0

正如d'alar'cop所说,我认为这可能是SQL语句的问题,而不是列表的问题。但无论如何,我会这样做:

int i = 1;
List<Long> newList = new ArrayList<Long>();
for(Long item : dbList)
    {
        for (i <= 10; i++)
        {
            newList.Add(item)

            if (i == 10)
            {
                //SQL Statement
                i = 1;
            }

            break;
        }

    }

或者,像其他人提到的那样,subList 也可以工作,并且可能是一种更紧凑的解决方案。


== 不是 =,用于 if 语句... 这样会导致无限循环。我想你想要的是遍历所有项。例如当 i 可以被 10 整除时,执行 SQL。 - Nate-Wilkins
好的,我修复了 if 语句的等式判断,而且我 认为 我通过使用 break 解决了无限循环的问题,但肯定有更好的解决方法。 - Daniel Underwood
几乎......你需要一个计数器来跟踪你正在处理哪个项目。现在它进入了for each,然后进入下一个计数10的for。你在一个项目上计算10,将10个项目添加到newList中。我建议打开eclipse并逐步执行你的代码,因为你错过了一些关键点。 - Nate-Wilkins
我的错。我曾认为break是快速退出for循环并进入列表中的下一项的方法。 - Daniel Underwood
1
是的,对程序流程进行仔细思考非常重要,目前代码只是将dbList填充到newList中。 - Nate-Wilkins

0

我不确定你想要做什么,但如果你无论如何都要用循环来构建查询,可以尝试以下伪代码:

counter=0;
for (Long item : dbList){
    query.add (item);
    if (counter>10){
        query.send();
        counter=0;
    }
}
if (!query.empty())
    query.send();

这只是伪代码。可能你没有像这样的查询对象,但这只是为了解释我的观点。

希望它有所帮助。


0
以下的代码片段可能会有所帮助。
     int pointer =0;
     List<Long> chunks = null;
     List<Long> longValues =    LongStream.rangeClosed(1, 100).boxed().collect(Collectors.toList());
     int limit =10;
     do{ 
             chunks = new ArrayList<>();
             for(int incrementor =pointer ; incrementor < longValues.size() && incrementor < pointer+limit; incrementor++){
                 chunks.add(longValues.get(incrementor));
             }
             if(chunks.size() == limit){
                 pointer = pointer + limit;
             }

             if(chunks.size() >0){
                 System.out.println(chunks);
             //your update query goes here
             }
     }while(chunks.size() ==limit);

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