str*_*ash 20 java hibernate java-8 java-stream
最近我在很少的项目中看到很多代码使用流来过滤对象,比如:
library.stream()
.map(book -> book.getAuthor())
.filter(author -> author.getAge() >= 50)
.map(Author::getSurname)
.map(String::toUpperCase)
.distinct()
.limit(15)
.collect(toList()));
Run Code Online (Sandbox Code Playgroud)
使用它而不是直接HQL/SQL查询到数据库返回已经过滤的结果是否有任何好处.
第二种方法不是更快吗?
Hen*_*nry 31
如果数据最初来自数据库,最好在数据库中进行过滤,而不是获取所有内容并在本地过滤.
首先,数据库管理系统擅长过滤,它是主要工作的一部分,因此针对它进行了优化.也可以使用索引加速过滤.
其次,获取和传输许多记录并将数据解组成对象只是为了在进行本地过滤时丢掉大量数据而浪费带宽和计算资源.
Gho*_*ica 25
乍一看:溪流可以平行运行; 只需更改代码即可使用parallelStream().(免责声明:当然,如果只改变流类型将导致正确的结果,它取决于具体的上下文;但是,它可以很容易).
然后:流"邀请"使用lambda表达式.而这些又导致使用invoke_dynamic字节码指令; 与"老派"编写此类代码相比,有时会获得性能优势.(并澄清误解:invoke_dynamic是lambda的属性,而不是stream!)
这些将是现在更喜欢"流"解决方案的理由(从一般观点来看).
除此之外:它真的取决于...让我们来看看您的示例输入.这看起来像处理已经驻留在内存中的普通Java POJO,在某种集合中.直接在内存中处理这些对象肯定比去一些进程外数据库在那里工作更快!
但是,当然:当上述呼叫时,就像book.getAuthor()进行"深度探索"并实际与底层数据库交谈一样; 然后很有可能"在一个查询中完成整个事情"会给你带来更好的表现.
Jen*_*der 13
首先要意识到,您无法从这段代码中分辨出针对数据库发出的语句.很可能,收集了所有过滤,限制和映射,并且在调用collect所有信息后,用于构造匹配的SQL语句(或使用的任何查询语言)并发送到数据库.
考虑到这一点,使用流式API的原因有很多.
这是时髦的.Streams和lambdas对于大多数Java开发人员来说仍然是一个新手,所以当他们使用它时他们感觉很酷.
如果使用第一段中的内容,它实际上创建了一个很好的DSL来构造您的查询语句.Scalas Slick和.Net LINQ我知道的早期例子,虽然我假设有人在我出生之前很久就在LISP中构建类似的东西.
流可能是反应流并封装非阻塞API.虽然这些API非常好,因为它们不会强迫您在等待结果时阻止线程等资源.使用它们需要大量的回调或使用更好的基于流的API来处理结果.
他们更好地阅读命令式代码.也许在流中完成的处理不能[轻松/由作者]完成SQL.因此,替代方案不是SQL与Java(或您正在使用的语言),而是命令式Java或"功能"Java.后者经常读得更好.
所以有充分的理由使用这样的API.
尽管如此:在几乎所有情况下,当您可以将其卸载到数据库时,在应用程序中进行任何排序/过滤等都是一个坏主意.我目前唯一能想到的例外是你可以跳过整个往返数据库,因为你已经在本地获得了结果(例如在缓存中).
除非针对特定情况进行测量和验证,否则可能是好的或同样糟糕的.您通常希望对数据库进行这类查询的原因是(除其他外):
DB可以处理比java进程更大的数据
可以索引数据库中的查询(使它们更快)
另一方面,如果您的数据很小,那么使用Stream您的方式是有效的.编写这样的Stream管道非常易读(一旦你说 Streams足够好).
那么,理想情况下你的问题应该是 - 在数据库中进行缩减/过滤操作或获取所有记录并使用Streams在Java中执行它是否更好?
答案并不简单,任何给出"具体"答案的统计数据都不会推广到所有情况.
您正在谈论的操作最好在DB本身中完成,因为这是DB的设计目标,非常快速地处理数据.当然,通常在关系数据库的情况下,会有一些"簿记和锁定"用于确保独立事务不会最终导致数据不一致,但即使如此,DB在过滤方面也做得非常好数据,尤其是大型数据集.
如果您需要从相同数据中过滤不同的功能,我倾向于使用Java代码而不是数据库过滤数据.例如,现在您只获得作者的姓氏.如果你想获得作者所写的所有书籍,作者的年龄,作者的孩子,出生地等等.那么从数据库中只获得一个"只读"副本并使用并行流来获取不同的信息是有意义的来自相同的数据集.
| 归档时间: |
|
| 查看次数: |
6146 次 |
| 最近记录: |