java中无限大_Java 9中的无限集

java中无限大

一套

Set是元素的集合,从而在任何给定的元件Set只出现一次。

更正式地说,集合不包含元素e1e2对,因此e1.equals(e2)

我们可以像这样在Java 9中轻松创建Set

final Set<Integer> s = Set.of(1, 2, 3);
System.out.println(s);

这可能会产生以下输出:

[2, 3, 1]

上面产生的Set是不可变的,即它不能更改,并且也是有限的,因为Set有不同数量的元素,即三个。 未指定通过其读取方法(例如stream()iterator()forEach() )返回元素的顺序。

无限集

无限集包含无限数量的元素。 无限集的一个示例是所有整数的集合[…,-1,0,1,2,…],其中整数不是Java Integer类,而是根据整数的数学定义得出的整数,其中存在对于任何给定的整数n,始终为更大的整数n + 1。

有许多无限集,例如所有质数的集合,偶数整数的集合,斐波那契数的集合等。

由于明显的原因,我们无法预先计算和存储无限Java Set所有元素。 如果尝试,最终将耗尽内存。

我们必须问自己的一个基本问题是:对于我们拥有的Java类型,实际上是否存在无限集? 如果我们有一个Set<Byte>中有最多256个元素的Set ,这是远离无限的,同样的道理也适用于Short ,甚至Integer 。 毕竟,只有大约40亿个不同的Integer对象,如果使用位图表示成员身份,则可以在0.5 GB的空间中容纳Set<Integer> 。 尽管很大,但不是无限的。

但是,如果我们谈论的是LongString元素,那么至少实际上是在接近无限集。 要存储所有Long的位图,将需要许多PB内部存储空间。 真正的无限Set将是具有任意长度的字符[az]的所有可能组合的String Set

在继续之前,我想提一下,这篇文章中的代码也可以在GitHub上找到,如文章结尾处所述。

ImmutableStreamSet

为了摆脱存储Set元素的范式,我们可以创建一个ImmutableStreamSet ,仅通过其stream()方法定义Set的元素。 可以将ImmutableStreamSet定义为如下所示的FunctionalInterface

@FunctionalInterface
public interface ImmutableStreamSet<E> extends Set<E> {// This is the only method we need to implements@Overridepublic Stream<E> stream(); @Overridedefault int size() {return (int) stream().limit(Integer.MAX_VALUE).count();}@Overridedefault boolean contains(Object o) {return stream().anyMatch(e -> Objects.equals(e, o));}@Overridedefault boolean containsAll(Collection<?> c) {return (this == c) ? true : c.stream().allMatch(this::contains);}@Overridedefault boolean isEmpty() {return !stream().findAny().isPresent();}@Overridedefault <T> T[] toArray(T[] a) {return stream().collect(toList()).toArray(a);}@Overridedefault Object[] toArray() {return stream().toArray();}@Overridedefault Spliterator<E> spliterator() {return stream().spliterator();}@Overridedefault Iterator<E> iterator() {return stream().iterator();}@Overridedefault Stream<E> parallelStream() {return stream().parallel();}@Overridedefault void forEach(Consumer<? super E> action) {stream().forEach(action);}// We are immutable@Overridedefault boolean removeIf(Predicate<? super E> filter) {throw new UnsupportedOperationException();}@Overridedefault void clear() {throw new UnsupportedOperationException();}@Overridedefault boolean removeAll(Collection<?> c) {throw new UnsupportedOperationException();}@Overridedefault boolean retainAll(Collection<?> c) {throw new UnsupportedOperationException();}@Overridedefault boolean addAll(Collection<? extends E> c) {throw new UnsupportedOperationException();}@Overridedefault boolean remove(Object o) {throw new UnsupportedOperationException();}@Overridedefault boolean add(E e) {throw new UnsupportedOperationException();}static <E> ImmutableStreamSet<E> of(Supplier<Stream<E>> supplier) {// Check out GitHub to see how this Impl class is implementedreturn new ImmutableStreamSetImpl<>(supplier);}}

太棒了,现在我们只需提供像这样的流提供者就可以创建无限集:

ImmutableStreamSet<Long> setOfAllLong= LongStream.rangeClosed(Long.MIN_VALUE, Long.MAX_VALUE)::boxed;

这将创建一Set所有Long值(例如,具有2 ^ 64个元素)。 提供流提供程序时,必须确保遵守元素唯一性的Set属性。 考虑以下非法集:

final ImmutableStreamSet<Long> illegalSet = () -> Stream.of(1l, 2l, 1l);

显然,集合中发生11次两次,这使该对象违反了集合要求。

正如我们将看到的,最好创建我们正在考虑的无限集的具体类。 上面的默认实现的一个特殊问题是contains()方法可能非常慢。 阅读下一章,找出原因以及如何解决。

正长集

让我们假设我们要创建一个包含所有正长值的Set ,并且希望能够与其他Set和Object有效地使用Set 。 我们可以这样去做:

public final class PositiveLongSet implements ImmutableStreamSet<Long> {public static final PositiveLongSet INSTANCE = new PositiveLongSet();private PositiveLongSet() {}@Overridepublic Stream<Long> stream() {return LongStream.rangeClosed(1, Long.MAX_VALUE).boxed();}@Overridepublic int size() {return Integer.MAX_VALUE;}@Overridepublic boolean contains(Object o) {return SetUtil.contains(this, Long.class, other -> other > 0, o);}@Overridepublic boolean isEmpty() {return false;}@Overridepublic String toString() {return SetUtil.toString(this);}}

请注意,即使Set很大,我们如何遵守方法size()的形式要求,在该方法中我们返回Integer.MAX_VALUE 。 如果Set已在今天定义,则size()可能会返回long而不是int 。 但是在90年代初,内部RAM通常小于1 GB。 我们在类中使用了两种实用程序方法:

SetUtil.toString()采用Set ,对前八个元素进行迭代,并返回这些元素的String表示形式。

SetUtil.contains()方法采用Set ,Element类型类(此处为Long.class )和Predicate ,如果我们Long.class比较的对象属于给定Element类型类(如果我们要比较的对象是null或其他类型,则该Set不包含该对象)。

这是SetUtil样子:

final class SetUtil {private static final int TO_STRING_MAX_ELEMENTS = 8;static <E> String toString(Set<E> set) {final List<String> first = set.stream().limit(TO_STRING_MAX_ELEMENTS + 1).map(Object::toString).collect(toList());final String endMarker = first.size() > TO_STRING_MAX_ELEMENTS ? ", ...]" : "]";return first.stream().limit(TO_STRING_MAX_ELEMENTS).collect(joining(", ", "[", endMarker));}static <E> boolean contains(final Set<E> set,final Class<E> clazz,final Predicate<E> predicate,final Object o) {if (o == null) {return false;}if (!(clazz.isAssignableFrom(o.getClass()))) {return false;}final E other = clazz.cast(o);return predicate.test(other);}}

有了类ImmutableStreamSetSetUtil我们现在可以轻松地创建其他无限集,例如PostitiveEvenLongSet (以下未显示,请PrimeLongSet编写), PrimeLongSet (包含可以用Long表示的所有素数)甚至FibonacciLongSet (包含所有fibonacci数字)可以用Long表示)。 这些类如下所示:

PrimeLongSet

public final class PrimeLongSet implements ImmutableStreamSet<Long> {public static final PrimeLongSet INSTANCE = new PrimeLongSet();private PrimeLongSet() {}private static final LongPredicate IS_PRIME =x -> LongStream.rangeClosed(2, (long) Math.sqrt(x)).allMatch(n -> x % n != 0);@Overridepublic Stream<Long> stream() {return LongStream.rangeClosed(2, Long.MAX_VALUE).filter(IS_PRIME).boxed();}@Overridepublic int size() {return Integer.MAX_VALUE; }@Overridepublic boolean contains(Object o) {return SetUtil.contains(this, Long.class, IS_PRIME::test, o);}@Overridepublic boolean isEmpty() {return false;}@Overridepublic String toString() {return SetUtil.toString(this);}}

斐波那契长集

public final class FibonacciLongSet implements ImmutableStreamSet<Long> {public static final FibonacciLongSet INSTANCE = new FibonacciLongSet();private FibonacciLongSet() {}@Overridepublic Stream<Long> stream() {return Stream.concat(Stream.of(0l),Stream.iterate(new Fibonacci(0, 1), Fibonacci::next).mapToLong(Fibonacci::getAsLong).takeWhile(fib -> fib > 0).boxed());}@Overridepublic int size() {return 92;}@Overridepublic boolean contains(Object o) {return SetUtil.contains(this,Long.class,other -> stream().anyMatch(fib -> Objects.equals(fib, other)),o);}@Overridepublic boolean isEmpty() {return false;}@Overridepublic String toString() {return SetUtil.toString(this);}private static class Fibonacci {final long beforeLast;final long last;public Fibonacci(long beforeLast, long last) {this.beforeLast = beforeLast;this.last = last;}public Fibonacci next() {return new Fibonacci(last, last + beforeLast);}public long getAsLong() {return beforeLast + last;}}}

注意当长回绕为负值时,我们如何使用Stream::takeWhile中断流。 可以说,当我们进行预计算并提供92的大小时,我们正在“作弊”,但否则size()会慢一些。

缝合全部

通过为这些类的实例提供带有静态提供程序的接口,我们可以封装我们的预定义集,并确保在JVM中只有这样的一个实例,如下所示:

public interface Sets {static Set<Long> positiveLongSet() {return PositiveLongSet.INSTANCE;}static Set<Long> positiveEvenLongSet() {return PositiveEvenLongSet.INSTANCE;}static Set<Long> primeLongSet() {return PrimeLongSet.INSTANCE;}static Set<Long> fibonacciLongSet() {return FibonacciLongSet.INSTANCE;}}

我们还可以将代码封装在Java 9模块中,通过将SetsImmutableStreamSet类暴露在项目的最顶层包中,并将所有其他类放在名为“ internal”的包中(不公开),以确保仅可见SetsImmutableStreamSet类。 )。

这是我们如何module-info.java可能看起来像规定,两个外露类在com.speedment.infinite_sets在包等,并且实现类com.speedment.infinite_sets.internal

module-info.java

module com.speedment.infinite_sets {exports com.speedment.infinite_sets;
}

尝试一下

现在,我们可以通过首先声明现有模块的用法来创建另一个使用无限集的模块,如下所示:

module-info.java

module Infinite_sets_app {requires com.speedment.infinite_sets;
}

然后,我们可以访问模块的裸露部分。 这是尝试无限集的一种方法:

import static com.speedment.infinite_sets.Sets.*;
public class Main {public static void main(String[] args) {Stream.of(Set.of(1, 2, 3),positiveLongSet(),positiveEvenLongSet(),primeLongSet(),fibonacciLongSet()).forEachOrdered(System.out::println);// This actually completes fast due to identity equalitypositiveLongSet().containsAll(positiveLongSet());}}

这可能会产生以下输出:

[3, 2, 1]
[1, 2, 3, 4, 5, 6, 7, 8, ...]
[2, 4, 6, 8, 10, 12, 14, 16, ...]
[2, 3, 5, 7, 11, 13, 17, 19, ...]
[0, 1, 2, 3, 5, 8, 13, 21, ...]

参与GitHub

这篇文章中的源代码可以在GitHub上找到 。
游戏,设定和比赛…

翻译自: https://www.javacodegeeks.com/2018/06/infinite-sets-java.html

java中无限大

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/333322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中父类的私有数据和静态数据在内存中是如何存储的?

1.父类的成员变量&#xff08;包含私有变量&#xff09;和成员方法地址&#xff08;包含私有成员方法&#xff09;都存放在子类对象中。父类的私有变量和私有方法虽然在子类对象中&#xff0c;但是对于子类对象而言是不可见的&#xff0c;无法直接访问和调用&#xff0c;必须通…

在计算机中 用户程序,在用户计算机上的万维网客户程序是()

摘要&#xff1a;修理需检后不测&#xff0c;户计户程行修即进应立理&#xff0c;修理自行解体铅封拆动。维网客注意简述计的基本及其R引原则要点物设。和鱼观察态的动水色&#xff0c;户计户程天早塘一养殖应每晚巡池塘次。...修理需检后不测&#xff0c;户计户程行修即进应立…

snmp与java集成_轻松地与Java完全集成

snmp与java集成这里是如何不使用SQL&#xff0c;HQL&#xff0c;PHP&#xff0c;ASP&#xff0c;HTML&#xff0c;CSS或Javascript而是使用Vaadin的UI层和Speedment Stream ORM完全依赖Java编写完整堆栈数据库Web应用程序的方法。 是否曾经想过快速创建连接到您现有数据库的We…

Java代码块的学习

普通代码块 在方法体中定义的代码块。 public static void main(String[] args) {{int i 20;System.out.println(i);}System.out.println(i); // 访问不到变量 i}构造代码块 1.在方法外定义的非静态的代码块 2.先于构造方法执行。实际是先执行父类构造方法&#xff0c;接着…

北大计算机专业考研难不难,北京大学考研有多难 难考的原因是什么

每年都有很多学生在本科毕业后选择考研&#xff0c;北京大学作为我国顶尖名校&#xff0c;想通过考研进入这所大学的人更是多的数不过来。那么&#xff0c;北京大学考研有多难呢&#xff1f;北京大学考研很难吗首先清华北大的难度在于这个学校的综合实力和业内地位&#xff0c;…

gwt格式_活性GWT

gwt格式介绍 在过去的4到5年中&#xff0c;React式编程的普及程度得到了极大的提高。 这可以告诉我们&#xff0c;React性应用程序的用例现在比以往任何时候都有效。 后端系统上的压力已经增加&#xff0c;因此需要用最少的资源来处理这种压力。 响应式编程被认为是在减少资源消…

asp.net html2canvas,Vue 结合html2canvas和jsPDF实现html页面转pdf

结合html2canvas和jsPDF实现html页面转pdfBy&#xff1a;授客QQ&#xff1a;103355122实践环境win10Vue 2.9.6axios 0.18.0html2canvas 1.0.0-rc.3jspdf 1.5.3安装 html2canvas进入vue项目所在目录,然后执行以下安装命令cd /d E:\MyProjects\TMP\frontendE:\MyProjects\TMP\fro…

Java中如何获取字符串的Unicode编码

public class UnicodeUtils {public static void main(String[] args) {String s "我爱你s";System.out.println(getUnicode(s)); // \u6211\u7231\u4f60\u0073}/*** 获取字符串的Unicode&#xff0c;即将字符串转化成Unicode* param str* return String * throws *…

穹顶灯打不出阴暗面_Java生产监控的阴暗面

穹顶灯打不出阴暗面自动化的工作流程是在敏捷环境中交付最优质产品的新金标准。 不幸的是&#xff0c;不断变化会带来不断的风险。 输入“可观察性”&#xff0c;这是一种度量&#xff0c;可以从其外部输出中推断出系统的内部状态。 知道应用程序如何在生产中运行的能力。 在本…

计算机软件高级证书试题,高级程序员认证考试经验总结

我今年5月23日参加了计算机水平考试的软件设计师(高级程序员)级别考试&#xff0c;当时报考的目的是想通过该级别的考试&#xff0c;证明自己的水平&#xff0c;工夫不负有心人&#xff0c;考了54/54。我考了两次&#xff0c;第一次是去年10月份考的&#xff0c;考了42/52&…

计算机考试视频教程江西,江西计算机二级自学教程推荐:公共基础知识(2018年版)...

&nbsp&nbsp[导读]:江西计算机二级自学教程推荐&#xff1a;公共基础知识(2018年版)&#xff0c;更多计算机等级考试用书、考试内容和考试模拟试题&#xff0c;请访问易考吧计算机等级网江西计算机二级自学教程推荐&#xff1a;公共基础知识(2018年版)喜讯&#xff1a;易…

java ldap操作实例_Java Spring Security示例教程中的2种设置LDAP Active Directory身份验证的方法...

java ldap操作实例LDAP身份验证是世界上最流行的企业应用程序身份验证机制之一&#xff0c;而Active Directory &#xff08;Microsoft为Windows提供的LDAP实现&#xff09;是另一种广泛使用的LDAP服务器。 在许多项目中&#xff0c;我们需要通过登录屏幕中提供的凭据使用LDAP对…

IntelliJ IDEA 修改单行注释的格式

文章目录修改 Java 编码中单行注释的格式修改 HTML 编码中单行注释的格式修改 Java 编码中单行注释的格式 根据下图所示的步骤进行设置&#xff1a; 成功设置后&#xff0c;单行注释的格式如下图所示&#xff1a; 修改 HTML 编码中单行注释的格式

目前的计算机系统属于第三代电子计算机,计算机应用基础判断题

计算机 练习题44、 计算机的硬件系统由控制器、显示器、打印机、主机、键盘组成。( )45、 计算机的内存储器与硬盘存储器相比&#xff0c;内存储器存储量大。( )46、 在计算机中&#xff0c;1000K称为一个M。( )47、 在计算机中&#xff0c;1024B称为一个KB。( √ )48、 计算…

synology smb_用于在Synology NAS上测试Spring Boot Web应用程序的JUnit模拟文件

synology smb对于将在Synology RS815 NAS上检查备份文件的Spring Boot应用程序&#xff0c;我们希望能够轻松测试此NAS上存储的文件&#xff0c;而不必复制存储在其上的7TB。 理想情况下&#xff0c;我们希望创建相同的文件结构以在Spring开发配置文件中使用Web应用程序&…

Sublime Text for Mac如何支持GBK编码

需要安装相关的字符编码插件&#xff0c;你可以安装以下三款插件&#xff1a; 1.ConvertToUTF8 &#xff1a;GBK 转 UTF8 插件 推荐安装这个&#xff0c;这个插件不仅可以解决 GBK 的问题&#xff0c;还可以解决其它的编码问题。 In most cases, this plug-in will take car…

常州全国计算机考点,2017年常州高考考点及考场查询系统

出国留学网高考考场查询频道为大家提供2017年常州高考考点及考场查询系统&#xff0c;更多高考准考证及高考考场信息请关注我们网站的更新!猜你喜欢&#xff1a;进场及出场后一、“穿”“带”双齐进考场。穿着整齐进考场&#xff0c;不要穿拖鞋&#xff0c;背心等。带齐考试用品…

vmware用户名和密码_VMWare vijava –“用户名或密码不正确”异常的奇怪情况

vmware用户名和密码在我参与的一个项目中&#xff0c;我们使用yavijava &#xff08;这是vijava的分支 &#xff09;库与托管我们的VM的vCenter进行交互。 vCenter通过其Web服务端点公开了各种API&#xff0c;这些API通过HTTP调用。 yavijava库具有必要的钩子&#xff0c;允许开…