将列表划分为大致相等的部分的最佳方法是什么?例如,如果列表有7个元素并将其拆分为2个部分,我们希望在一个部分中获得3个元素,而另一个应该具有4个元素.
我正在寻找像even_split(L, n)这样的东西L分成n几部分.
def chunks(L, n):
""" Yield successive n-sized chunks from L.
"""
for i in xrange(0, len(L), n):
yield L[i:i+n]
Run Code Online (Sandbox Code Playgroud)
上面的代码给出了3个块,而不是3个块.我可以简单地转置(迭代它并获取每列的第一个元素,调用第一部分,然后取第二部分并将其放入第二部分等),但这会破坏项目的顺序.
是否可以将纯Jdk8中的List分区为相等的块(子列表).
我知道可以使用Guava Lists类,但是我们可以使用纯Jdk吗?我不想在我的项目中添加新的jar,仅用于一个用例.
解决方案:
tagir-valeev提出了迄今为止最好的解决方案:
我还发现了其他三种可能性,但它们只适用于少数情况:
1.Collectors.partitioningBy()将列表拆分为2个子列表 - 如下所示:
intList.stream().collect(Collectors.partitioningBy(s -> s > 6));
List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());
Run Code Online (Sandbox Code Playgroud)
2.Collectors.groupingBy()将我们的列表拆分为多个分区:
Map<Integer, List<Integer>> groups =
intList.stream().collect(Collectors.groupingBy(s -> (s - 1) / 3));
List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());
Run Code Online (Sandbox Code Playgroud)
3.分离器分离:
List<Integer> intList = Lists.newArrayList(1, 2, 3, 0, 4, 5, 6, 0, 7, 8);
int[] indexes =
Stream.of(IntStream.of(-1), IntStream.range(0, intList.size())
.filter(i -> intList.get(i) == 0), IntStream.of(intList.size()))
.flatMapToInt(s -> s).toArray();
List<List<Integer>> subSets =
IntStream.range(0, indexes.length - 1)
.mapToObj(i …Run Code Online (Sandbox Code Playgroud) 我正在尝试将列表拆分为列表,其中每个列表的最大大小为4.
我想知道如何使用lambdas做到这一点.
目前我正在这样做的方式如下:
List<List<Object>> listOfList = new ArrayList<>();
final int MAX_ROW_LENGTH = 4;
int startIndex =0;
while(startIndex <= listToSplit.size() )
{
int endIndex = ( ( startIndex+MAX_ROW_LENGTH ) < listToSplit.size() ) ? startIndex+MAX_ROW_LENGTH : listToSplit.size();
listOfList.add(new ArrayList<>(listToSplit.subList(startIndex, endIndex)));
startIndex = startIndex+MAX_ROW_LENGTH;
}
Run Code Online (Sandbox Code Playgroud)
UPDATE
似乎没有一种简单的方法可以使用lambdas来拆分列表.虽然所有的答案都非常受欢迎,但它们也是lambdas不简化事物的一个很好的例子.
我有一个问题是使用deleteInBatch从db中删除项目.我有一个对象A有一个对象B列表,如:
class A {
private List <B>;
}
Run Code Online (Sandbox Code Playgroud)
该列表包含7k多个元素.所以现在我必须删除A及其所有元素.我试过通过deleteInBatch,但我得到了
org.springframework.web.util.NestedServletException: Handler processing failed;
nested exception is java.lang.StackOverflowError
Run Code Online (Sandbox Code Playgroud)
使用sipmle delete方法删除项目有效,但需要5分钟以上.我的删除代码是:
public void delete(Long id) {
A a = repository.findOne(id);
deleteElements(a);
repository.delete(a);
}
private void deleteElements(A a) {
repository.deleteInBatch(a.getListOfB);
}
Run Code Online (Sandbox Code Playgroud)
有没有一个很好的解决方案来加快删除过程或如何更改,以便deleteinbatch不占用所有休眠堆栈 - 不增加它?
完整的Stacktrace:
org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.StackOverflowError
org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletionWithError(DispatcherServlet.java:1259)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:163)
net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:206)
net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:179)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
Run Code Online (Sandbox Code Playgroud)
等等...
root cause
java.lang.StackOverflowError
org.hibernate.hql.internal.ast.tree.SqlNode.<init>(SqlNode.java:34)
sun.reflect.GeneratedConstructorAccessor36.newInstance(Unknown Source)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:526)
java.lang.Class.newInstance(Class.java:379)
org.hibernate.hql.internal.ast.SqlASTFactory.create(SqlASTFactory.java:256)
antlr.ASTFactory.create(ASTFactory.java:153)
antlr.ASTFactory.create(ASTFactory.java:186) …Run Code Online (Sandbox Code Playgroud) 我想以小批量大小迭代ArrayList.
例如,如果ArrayList大小为75且批量大小为10,我希望它处理0-10,然后是10-20,然后是20-30等记录.
我试过这个,但它不起作用:
int batchSize = 10;
int start = 0;
int end = batchSize;
for(int counter = start ; counter < end ; counter ++)
{
if (start > list.size())
{
System.out.println("breaking");
break;
}
System.out.println("counter " + counter);
start = start + batchSize;
end = end + batchSize;
}
Run Code Online (Sandbox Code Playgroud)