【问题标题】:Does java have an equivalent of mysql's limit and offset for arraylists?java对arraylists是否有相当于mysql的限制和偏移量?
【发布时间】:2018-11-20 01:12:49
【问题描述】:

在 MySQL 中你可以这样做:

select * from sometable order by id desc limit 3 offset 0; 

这将返回前 3 个结果。在java中如何实现这样的事情?

如果我有一个奇数元素的ArrayList

ArrayList<String> ids = new ArrayList<String>();
ids.add("1");
ids.add("2");
ids.add("3");
ids.add("4");
ids.add("5");
ids.add("6");
ids.add("7");
ids.add("8");
ids.add("9");
ids.add("10");
ids.add("11");

如何从这个ArrayList 中为每个偏移量只获得 3 个结果(或者如果没有更多元素,则少于 3 个)?

例如,假设限制总是 3 和offset = 0

它应该吐出 1,2,3

if offset = 3:

4,5,6

offset = 6:

7,8,9

offset = 9:

10,11

我目前的做法是创建列表的子列表:

int endOf = offset+3;
ArrayList<String> ids2 = new ArrayList<String>(ids.subList(offset, endOf));

但是当偏移量大于id的大小时它会中断......

如果数组列表不能做到这一点,有没有更好的方法来做到这一点?

编辑:

基于这两个答案,Andy 的方法似乎表现更好:

long startTime = System.nanoTime();
 //tried each method here
long stopTime = System.nanoTime();
System.out.println(stopTime - startTime);

没有流:

40960
17167
13854
10240

使用流:

303584
118060
47284
40357

EDIT2:

绝对不应依赖上述基准测试。欲了解更多信息,请参见此处:How do I write a correct micro-benchmark in Java?

【问题讨论】:

标签: java mysql list limit offset


【解决方案1】:

这可以通过流来完成:

List<Integer> result = 
    ids.stream()
       .skip(0)  // Equivalent to SQL's offset
       .limit(3) // Equivalent to SQL's limit
       .collect(Collectors.toList());

【讨论】:

    【解决方案2】:

    只需钳制subList的参数即可:

    list.subList(
        Math.min(list.size(), offset),
        Math.min(list.size(), offset + limit))
    

    如果你觉得语法不方便,写一个辅助方法,例如

    <T> List<T> clampedSublist(List<T> list, int offset, int limit)
    

    【讨论】:

    • @JonathanLaliberte 要记住的一件事是流方法创建一个新列表,而这只是返回列表的视图,即 O(lim) 存储与 O(1)。跨度>
    • @JonathanLaliberte 是的。
    • @JonathanLaliberte 不要简单地相信我的话。测量应用程序中的差异。如果没有显着差异,或者差异无关紧要,请选择您认为最容易的一个。
    • @JonathanLaliberte 另见:stackoverflow.com/questions/504103/…
    • 您还必须考虑的一件事是subList 为您提供了原始列表的视图。来自 JavaDoc:返回的列表受此列表的支持,因此返回列表中的非结构性更改会反映在此列表中,反之亦然。 请参阅 this question。所以如果你需要一个独立的列表,你必须创建一个子列表的副本(new ArrayList&lt;&gt;(...) 或类似的)。
    【解决方案3】:
    List<Integer> result = 
        ids.stream()
           .skip(0)  // Equivalent to SQL's offset
           .limit(3) // Equivalent to SQL's limit
           .collect(Collectors.toList());
    

    跳过应该是pagenolimit

    【讨论】:

    • 为了使这个答案有用,进一步的解释将大有帮助。
    猜你喜欢
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 2021-12-29
    • 1970-01-01
    • 2016-06-09
    相关资源
    最近更新 更多