java的整数序列_Java中整型的短序列

Java中整型的短序列

生成一个List ,或者一个Integer[]或者int[] ,必须有一个简短而可爱的方法,用从某个start值到end值的顺序值。

也就是说,比以下更短,但相当于1 :

void List makeSequence(int begin, int end) { List ret = new ArrayList<>(end - begin + 1); for (int i=begin; i<=end; i++) { ret.add(i); } return ret; }

…但是它在逃避我 使用番石榴是好的。

更新:

性能分析

由于这个问题已经得到了几个很好的答案,无论是使用原生Java 8和第三方库,我想我会testing所有解决scheme的性能。

第一个testing简单地使用以下方法testing创build一个包含10个元素的列表[1..10] :

classicArrayList :在我的问题上面给出的代码(和adarshr的答案基本相同)。

eclipseCollections :使用Eclipse Collections 8.0在Donald的答案中给出的代码。

guavaRange : daveb在下面的答案给出的代码。 从技术上讲,这不会创build一个List而是创build一个ContiguousSet – 但是由于它实现了Iterable ,所以它主要用于我的目的。

intStreamRange :在下面的Vladimir的答案中给出的代码,它使用IntStream.rangeClosed() – 它是在Java 8中引入的。

streamIterate :在Catalin的答案中给出的代码也使用了Java 8中引入的IntStreamfunction。

以下是每秒千次操作的结果(更高的数字更好),以上所有的大小为10的列表:

968b045e86a751442e9a6f9f1045ae57.png

…并再次列出大小为10,000的列表:

e53b0735e3558efea36006333e49e004.png

最后一张图是正确的 – 除Eclipse和Guava以外的解决scheme太慢,甚至没有单个像素栏! 快速解决scheme比其他解决scheme快10,000到20,000 倍 。

当然,这里的番石榴和日食解决scheme实际上并没有实现任何10,000种元素列表 – 它们仅仅是开始和结束点的固定大小的包装。 每个元素都是在迭代过程中根据需要创build的。 由于我们实际上并没有在这个testing中进行迭代,所以成本是延迟的。 所有其他的解决scheme实际上已经在内存中实现了完整的列表,并且在仅创build的基准中付出了沉重的代价。

让我们做一些更现实的事情,也遍历所有的整数,总结它们。 因此,在IntStream.rangeClosed变体的情况下,基准看起来像:

@Benchmark public int intStreamRange() { List ret = IntStream.rangeClosed(begin, end).boxed().collect(Collectors.toList()); int total = 0; for (int i : ret) { total += i; } return total; }

在这里,图片变化很大,虽然非物质化解决scheme仍然是最快的。 这是长度= 10:

a5f9a6d83818a8a35096f209bcc9168f.png

…和长度= 10,000:

b9bda0d35bb8ed0414d5678275ff8812.png

对许多元素的长期迭代使得事情变得很多,但即使在10,000元素testing中,日食和番石榴的速度仍然是两倍以上。

所以,如果你真的想要一个List ,eclipse集合看起来是最好的select – 但是当然如果你以更原生的方式使用stream(例如,忘记.boxed()和缩小原始域)可能会比所有这些变种更快。

1也许除了error handling,例如,如果end < begin ,或者如果大小超过了一些实现或JVM限制(例如大于2^31-1数组)。

使用Java 8,它非常简单,所以它甚至不需要单独的方法:

List range = IntStream.rangeClosed(start, end) .boxed().collect(Collectors.toList());

那么,这一class轮可能有资格(使用番石榴山脉 )

ContiguousSet integerList = ContiguousSet.create(Range.closedOpen(0, 10), DiscreteDomain.integers()); System.out.println(integerList);

这不会创build一个List ,但是ContiguousSet提供了很多相同的function,特别是实现Integer ,它允许以与List相同的方式实现foreach 。

在较早的版本(Guava 14之前的某个地方),你可以使用这个:

ImmutableList integerList = Ranges.closedOpen(0, 10).asSet(DiscreteDomains.integers()).asList(); System.out.println(integerList);

两者都产生:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

这是使用Core Java的最短时间。

List makeSequence(int begin, int end) { List ret = new ArrayList(end - begin + 1); for(int i = begin; i <= end; i++, ret.add(i)); return ret; }

您可以使用Eclipse集合中的Interval类。

List range = Interval.oneTo(10); range.forEach(System.out::print); // prints 12345678910

Interval类是惰性的,所以不存储所有的值。

LazyIterable range = Interval.oneTo(10); System.out.println(range.makeString(",")); // prints 1,2,3,4,5,6,7,8,9,10

你的方法可以实现如下:

public List makeSequence(int begin, int end) { return Interval.fromTo(begin, end); }

如果你想避免装饰整数作为整数,但仍然喜欢一个列表结构作为结果,那么你可以从Eclipse集合IntList使用IntInterval 。

public IntList makeSequence(int begin, int end) { return IntInterval.fromTo(begin, end); }

IntList具有IntList的方法sum() , min() , minIfEmpty() , max() , maxIfEmpty() , average()和median() 。

注意:我是Eclipse集合的提交者

以下单线程Java 8版本将生成[1,2,3 … 10]。 iterate的第一个参数是序列中的第一个参数, limit的第一个参数是最后一个参数。

List numbers = Stream.iterate(1, n -> n + 1) .limit(10) .collect(Collectors.toList());

你可以使用番石榴山脉

你可以通过使用获得一个SortedSet

ImmutableSortedSet set = Ranges.open(1, 5).asSet(DiscreteDomains.integers()); // set contains [2, 3, 4]

这是我能find的最短的。

列表版本

public List makeSequence(int begin, int end) { List ret = new ArrayList(++end - begin); for (; begin < end; ) ret.add(begin++); return ret; }

arrays版本

public int[] makeSequence(int begin, int end) { if(end < begin) return null; int[] ret = new int[++end - begin]; for (int i=0; begin < end; ) ret[i++] = begin++; return ret; }

这个可能适合你…

void List makeSequence(int begin, int end) { AtomicInteger ai=new AtomicInteger(begin); List ret = new ArrayList(end-begin+1); while ( end-->begin) { ret.add(ai.getAndIncrement()); } return ret; }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值