[英]Akka stream sort by id in java
我需要在java中按id對我的akka流列表進行排序我在akka源中有對象列表:
SystemCodeTracking{id=9, EntityName='table3'}
SystemCodeTracking{id=2, EntityName='table2'}
SystemCodeTracking{id=10, EntityName='table1'}
我需要將其排序為:
SystemCodeTracking{id=2, EntityName='table2'}
SystemCodeTracking{id=9, EntityName='table3'}
SystemCodeTracking{id=10, EntityName='table1'}
代碼應如下所示:
Source<SystemCodeTracking, SourceQueueWithComplete<SystemCodeTracking>> loggedSource = source.map(single -> sortingFunction(single));
我的問題是如何做sortingFunction
?
排序基本上會破壞流的性質,因為您需要消耗整個流 - 即將其裝入內存 - 以應用排序功能。 無論如何,可以通過將整個源耗盡到Sink.seq
,然后對結果進行排序。
source.runWith(Sink.seq, materializer)
然后在完成階段結果調用
sortingFunction(result)
如果您想對源代碼的塊進行排序,而不是對整個內容進行排序,則可以執行以下操作
source.grouped(10).map(batch -> sortingFunction(batch))
如果找不到該序列的最小元素(將在結果排序流中首先發出),則無法對序列進行排序(無論是 Akka Stream 還是其他任何東西)。 如果流是無限的,通常就是這種情況。
在某些情況下,您甚至可以對無限流進行排序,即使在低內存限制內 - 例如,如果您可以通過僅查看 N 個最后一個元素來確定下一個最小元素。 或者您可以利用特定於案例的知識,當滿足some_condition時,您可以確保some_class元素永遠不會出現在您的流中。
否則,您唯一的選擇就是將排序問題升級一級:您真的需要流中的強順序嗎? 也許僅僅對流進行分區就足夠了——即將它分成具有相同鍵的元素的子流?
我想 Akka Streams 沒有Flow.sort
的原因是 Akka Streams 都是關於資源消耗的有界性,並且Flow.sort
進行排序需要 O(n) 的內存。
根據定義,流是無界的 => 提供完美的排序需要在發出第一個數據之前觀察所有數據。
然而,在很多情況下,可以假設流只是部分未排序,也就是說,由於並發處理,數據會稍微混淆,盡管每個元素最終不會超過 1000 個位置它的真實位置。
在這種情況下,您可以使用帶有緩沖區的排序方法,如下所示:
* partial sort of a stream: wait for <bufferSize> to be buffered, the start flushing them out in order
* */
def sort[T, S](bufferSize: Int, order: T => S)(implicit ordering: Ordering[S]): () => T => Iterable[T] = () => {
var buffer = List.empty[T]
t: T => {
buffer = (buffer :+ t).sortBy(order)
if (buffer.size < bufferSize) Iterable.empty[T]
else {
val r = buffer.head
buffer = buffer.tail
List(r)
}
}
}
它可以簡單地用作statefulMapConcat
一部分,如下所示:
someSource
// sort the stream by timestpam, using a buffer of 1000,
.statefulMapConcat(sort(1000, _.timestamp))
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.