我開始學習 Java Stream,我想知道是否可以只查看流的第一個元素而不檢索它。
例如,我有多個流,每個流都有以非降序排序的整數,我想獲得所有整數的排序串列,所以我正在考慮使用PrioirtyQueue<Stream>非降序排序作為好。
但是,為了PrioirtyQueue<Stream>對流進行排序,我需要為流傳遞一個比較器,以按流的第一個元素比較流,并且我不確定如何查看每個流中的第一個元素。
例如,我有以下流。
[1, 2, 3, 5],
[0, 2, 4, 6]
我想撰寫一個函式getNextInteger(),處理排序流的串列。
每次我呼叫該方法時,它都會回傳下一個最小整數,因此[0,1,2,2]如果我呼叫該方法4次,結果可能是。
我想用PriorityQueue它們的第一個值對流進行排序,如果它不為空,則檢索最小的流并重新排隊。
uj5u.com熱心網友回復:
Stream 是對資料源進行迭代的一種方法,它的目的是處理資料,而不是存盤資料。
因此,您的問題本質上是不正確的。最簡潔的答案是不。
它不是資料結構,您不能像訪問a或 a 中的元素一樣訪問流中的元素。ListQueue
看看檔案:
集合和流雖然有一些表面上的相似之處,但有不同的目標。館藏主要關注其元素的有效管理和訪問。相比之下, 流不提供直接訪問或操作其 元素的方法,而是關注以宣告方式描述其源以及將在該源上聚合執行的計算操作。
正如我所說,流是迭代的平均值,但流管道也不同于Iterator. AnIterator允許一個一個地檢索元素。相反,流管道將被執行并產生結果(作為單個值或值的集合)并且將被關閉或不會被執行。這將取決于流是否具有終端操作。
例如,這個流是有效的,它會編譯得很好,但它不會被執行:
Stream.of("a", "b", "c").map(String::toUpperCase);
因為它缺少終端操作。
每個流都應該有一個源和一個觸發管道執行并產生結果的終端操作。用于轉換流的中間操作(如map()and filter())是可選的。
您無法從流中獲取資料而不對其進行處理。而且一旦處理完畢,就不能再使用了。
作為解決此問題的一種可能方法,您可以考慮用一個物件包裝流,該物件將分別維護來自流源的第一個元素和流本身。
public record StreamWrapper(int first, IntStream stream) {}
可以使用該方法,通過單個值比較流就足夠了,該值應在生成流的同時從流源中提取(如果流源允許)。
更新
我想撰寫一個函式 getNextInteger(),它處理已 排序流的串列。
每次我呼叫該方法時,它都會回傳下一個最小整數,因此
[0,1,2,2]如果我呼叫該方法4次,結果可能是。
該任務不適合流。除非您對每個流中的資料已經排序這一事實視而不見。
如果我們將所有流合并為一個并應用排序,它不會像一開始看起來那樣造成巨大的性能損失。為了對資料流進行排序,將所有元素轉儲到一個陣列中,在這種情況下,該陣列將由已排序的子陣列組成。因為參考型別的陣列將使用Timsort進行排序,所以演算法實作將發現所有這些已排序的塊。即對由部分排序的子陣列組成的陣列進行排序與??從頭開始對所有這些資料進行排序不同。因此,我們可以將其視為一種可能的選擇:
List<Stream<Integer>> streams =
List.of(Stream.of(1, 3), Stream.of(5), Stream.of(2, 6, 7),
Stream.of(4, 9, 10), Stream.of(8));
streams.stream()
.flatMap(Function.identity())
.sorted()
.forEach(num -> System.out.print(num " "));
將產生一個輸出:
1 2 3 4 5 6 7 8 9 10
如果列印(或存盤到集合中)按升序排序的整體資料似乎不令人滿意,并且您堅持只檢索一個值作為方法呼叫的結果,我將重申不可能通過一個連續從溪流。
為此,您需要Iterator按照檔案的建議:
但是,如果提供的流操作不提供所需的功能,則
BaseStream.iterator()和BaseStream.spliterator()操作可用于執行受控遍歷。
您可以實作一個custom iterator將PriorityQueue在引擎蓋下使用的 a。
我假設流的型別是實作Comparable并且流是排序的(就像您提供的示例一樣)。
迭代器:
public class QueueBasedIterator<T extends Comparable<T>> implements Iterator<T> {
private Queue<IteratorWrapper<T>> nextValues = new PriorityQueue<>();
private List<Iterator> iterators = new ArrayList<>();
@SafeVarargs
public StreamBasedIterator(Stream<T>... streams) {
this.iterators = Stream.of(streams).map(Stream::iterator)
.collect(Collectors.toList());
for (int i = 0; i < iterators.size(); i ) {
Iterator<T> iterator = iterators.get(i);
if (iterator.hasNext())
nextValues.add(new IteratorWrapper<T>(i, iterator.next()));
}
}
@Override
public boolean hasNext() {
return !nextValues.isEmpty();
}
@Override
public T next() {
if (nextValues.isEmpty()) {
throw new NoSuchElementException();
}
IteratorWrapper<T> next = nextValues.remove();
Iterator<T> iterator = iterators.get(next.getPosition());
if (iterator.hasNext())
nextValues.add(new IteratorWrapper<T>(next.getPosition(), iterator.next()));
return next.getValue();
}
}
迭代器包裝器:
class IteratorWrapper<T extends Comparable<T>> implements Comparable<IteratorWrapper<T>> {
private T value;
private int position;
public IteratorWrapper(int position, T value) {
this.value = value;
this.position = position;
}
public T getValue() {
return value;
}
public int getPosition() {
return position;
}
@Override
public int compareTo(IteratorWrapper<T> o) {
return this.value.compareTo(o.value);
}
}
main()- 演示
public static void main(String[] args) {
QueueBasedIterator<Integer> iterator =
new QueueBasedIterator<>(Stream.of(1, 3), Stream.of(5), Stream.of(2, 6, 7),
Stream.of(4, 9, 10), Stream.of(8));
while (iterator.hasNext()) {
System.out.print(iterator.next() " ");
}
}
輸出
1 2 3 4 5 6 7 8 9 10
uj5u.com熱心網友回復:
我想知道是否可以只查看流的第一個元素而不檢索它。
No. Peek是intermediate operation, likemap, sort等。它們不會導致流開始傳送資料。要做到這一點,需要一個terminal operation諸如reduce, forEach, or collector,等等來啟動流式處理。
這也允許人們在不存盤任何資料的情況下執行以下操作。如果是這樣,第一個陳述句 ( series) 將永遠不會完成,因為它需要無限存盤,因為沒有限制方法。
IntStream series = IntStream.iterate(0, i->i 1);
IntStream first10 = series.limit(10);
int[] toArray = first10.toArray();
System.out.println(Arrays.toString(toArray));
印刷
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
在上面的示例中,toArray()是啟動流的終端操作。一旦完成,流將被耗盡,并且上述分配(例如series, first10)都不能再次使用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/476937.html
下一篇:按數字對數字進行排序
