Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
da485e25
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
da485e25
编写于
6月 05, 2019
作者:
S
shade
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8075939: Stream.flatMap() causes breaking of short-circuiting of terminal operations
Reviewed-by: forax, smarks, andrew
上级
8844d081
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
263 addition
and
50 deletion
+263
-50
src/share/classes/java/util/stream/DoublePipeline.java
src/share/classes/java/util/stream/DoublePipeline.java
+26
-4
src/share/classes/java/util/stream/IntPipeline.java
src/share/classes/java/util/stream/IntPipeline.java
+26
-4
src/share/classes/java/util/stream/LongPipeline.java
src/share/classes/java/util/stream/LongPipeline.java
+26
-4
src/share/classes/java/util/stream/ReferencePipeline.java
src/share/classes/java/util/stream/ReferencePipeline.java
+83
-16
src/share/classes/java/util/stream/SortedOps.java
src/share/classes/java/util/stream/SortedOps.java
+25
-17
test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java
...est/org/openjdk/tests/java/util/stream/FlatMapOpTest.java
+77
-5
未找到文件。
src/share/classes/java/util/stream/DoublePipeline.java
浏览文件 @
da485e25
/*
/*
* Copyright (c) 2013, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -260,6 +260,12 @@ abstract class DoublePipeline<E_IN>
...
@@ -260,6 +260,12 @@ abstract class DoublePipeline<E_IN>
@Override
@Override
Sink
<
Double
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
Sink
<
Double
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedDouble
<
Double
>(
sink
)
{
return
new
Sink
.
ChainedDouble
<
Double
>(
sink
)
{
// true if cancellationRequested() has been called
boolean
cancellationRequestedCalled
;
// cache the consumer to avoid creation on every accepted element
DoubleConsumer
downstreamAsDouble
=
downstream:
:
accept
;
@Override
@Override
public
void
begin
(
long
size
)
{
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
downstream
.
begin
(-
1
);
...
@@ -268,11 +274,27 @@ abstract class DoublePipeline<E_IN>
...
@@ -268,11 +274,27 @@ abstract class DoublePipeline<E_IN>
@Override
@Override
public
void
accept
(
double
t
)
{
public
void
accept
(
double
t
)
{
try
(
DoubleStream
result
=
mapper
.
apply
(
t
))
{
try
(
DoubleStream
result
=
mapper
.
apply
(
t
))
{
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if
(
result
!=
null
)
{
if
(
result
!=
null
)
if
(!
cancellationRequestedCalled
)
{
result
.
sequential
().
forEach
(
i
->
downstream
.
accept
(
i
));
result
.
sequential
().
forEach
(
downstreamAsDouble
);
}
else
{
Spliterator
.
OfDouble
s
=
result
.
sequential
().
spliterator
();
do
{
}
while
(!
downstream
.
cancellationRequested
()
&&
s
.
tryAdvance
(
downstreamAsDouble
));
}
}
}
}
}
}
@Override
public
boolean
cancellationRequested
()
{
// If this method is called then an operation within the stream
// pipeline is short-circuiting (see AbstractPipeline.copyInto).
// Note that we cannot differentiate between an upstream or
// downstream operation
cancellationRequestedCalled
=
true
;
return
downstream
.
cancellationRequested
();
}
};
};
}
}
};
};
...
...
src/share/classes/java/util/stream/IntPipeline.java
浏览文件 @
da485e25
/*
/*
* Copyright (c) 2012, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -296,6 +296,12 @@ abstract class IntPipeline<E_IN>
...
@@ -296,6 +296,12 @@ abstract class IntPipeline<E_IN>
@Override
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedInt
<
Integer
>(
sink
)
{
return
new
Sink
.
ChainedInt
<
Integer
>(
sink
)
{
// true if cancellationRequested() has been called
boolean
cancellationRequestedCalled
;
// cache the consumer to avoid creation on every accepted element
IntConsumer
downstreamAsInt
=
downstream:
:
accept
;
@Override
@Override
public
void
begin
(
long
size
)
{
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
downstream
.
begin
(-
1
);
...
@@ -304,11 +310,27 @@ abstract class IntPipeline<E_IN>
...
@@ -304,11 +310,27 @@ abstract class IntPipeline<E_IN>
@Override
@Override
public
void
accept
(
int
t
)
{
public
void
accept
(
int
t
)
{
try
(
IntStream
result
=
mapper
.
apply
(
t
))
{
try
(
IntStream
result
=
mapper
.
apply
(
t
))
{
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if
(
result
!=
null
)
{
if
(
result
!=
null
)
if
(!
cancellationRequestedCalled
)
{
result
.
sequential
().
forEach
(
i
->
downstream
.
accept
(
i
));
result
.
sequential
().
forEach
(
downstreamAsInt
);
}
else
{
Spliterator
.
OfInt
s
=
result
.
sequential
().
spliterator
();
do
{
}
while
(!
downstream
.
cancellationRequested
()
&&
s
.
tryAdvance
(
downstreamAsInt
));
}
}
}
}
}
}
@Override
public
boolean
cancellationRequested
()
{
// If this method is called then an operation within the stream
// pipeline is short-circuiting (see AbstractPipeline.copyInto).
// Note that we cannot differentiate between an upstream or
// downstream operation
cancellationRequestedCalled
=
true
;
return
downstream
.
cancellationRequested
();
}
};
};
}
}
};
};
...
...
src/share/classes/java/util/stream/LongPipeline.java
浏览文件 @
da485e25
/*
/*
* Copyright (c) 2013, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -277,6 +277,12 @@ abstract class LongPipeline<E_IN>
...
@@ -277,6 +277,12 @@ abstract class LongPipeline<E_IN>
@Override
@Override
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedLong
<
Long
>(
sink
)
{
return
new
Sink
.
ChainedLong
<
Long
>(
sink
)
{
// true if cancellationRequested() has been called
boolean
cancellationRequestedCalled
;
// cache the consumer to avoid creation on every accepted element
LongConsumer
downstreamAsLong
=
downstream:
:
accept
;
@Override
@Override
public
void
begin
(
long
size
)
{
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
downstream
.
begin
(-
1
);
...
@@ -285,11 +291,27 @@ abstract class LongPipeline<E_IN>
...
@@ -285,11 +291,27 @@ abstract class LongPipeline<E_IN>
@Override
@Override
public
void
accept
(
long
t
)
{
public
void
accept
(
long
t
)
{
try
(
LongStream
result
=
mapper
.
apply
(
t
))
{
try
(
LongStream
result
=
mapper
.
apply
(
t
))
{
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if
(
result
!=
null
)
{
if
(
result
!=
null
)
if
(!
cancellationRequestedCalled
)
{
result
.
sequential
().
forEach
(
i
->
downstream
.
accept
(
i
));
result
.
sequential
().
forEach
(
downstreamAsLong
);
}
else
{
Spliterator
.
OfLong
s
=
result
.
sequential
().
spliterator
();
do
{
}
while
(!
downstream
.
cancellationRequested
()
&&
s
.
tryAdvance
(
downstreamAsLong
));
}
}
}
}
}
}
@Override
public
boolean
cancellationRequested
()
{
// If this method is called then an operation within the stream
// pipeline is short-circuiting (see AbstractPipeline.copyInto).
// Note that we cannot differentiate between an upstream or
// downstream operation
cancellationRequestedCalled
=
true
;
return
downstream
.
cancellationRequested
();
}
};
};
}
}
};
};
...
...
src/share/classes/java/util/stream/ReferencePipeline.java
浏览文件 @
da485e25
/*
/*
* Copyright (c) 2012, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -251,12 +251,14 @@ abstract class ReferencePipeline<P_IN, P_OUT>
...
@@ -251,12 +251,14 @@ abstract class ReferencePipeline<P_IN, P_OUT>
@Override
@Override
public
final
<
R
>
Stream
<
R
>
flatMap
(
Function
<?
super
P_OUT
,
?
extends
Stream
<?
extends
R
>>
mapper
)
{
public
final
<
R
>
Stream
<
R
>
flatMap
(
Function
<?
super
P_OUT
,
?
extends
Stream
<?
extends
R
>>
mapper
)
{
Objects
.
requireNonNull
(
mapper
);
Objects
.
requireNonNull
(
mapper
);
// We can do better than this, by polling cancellationRequested when stream is infinite
return
new
StatelessOp
<
P_OUT
,
R
>(
this
,
StreamShape
.
REFERENCE
,
return
new
StatelessOp
<
P_OUT
,
R
>(
this
,
StreamShape
.
REFERENCE
,
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
@Override
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
R
>
sink
)
{
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
R
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
R
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
R
>(
sink
)
{
// true if cancellationRequested() has been called
boolean
cancellationRequestedCalled
;
@Override
@Override
public
void
begin
(
long
size
)
{
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
downstream
.
begin
(-
1
);
...
@@ -265,11 +267,27 @@ abstract class ReferencePipeline<P_IN, P_OUT>
...
@@ -265,11 +267,27 @@ abstract class ReferencePipeline<P_IN, P_OUT>
@Override
@Override
public
void
accept
(
P_OUT
u
)
{
public
void
accept
(
P_OUT
u
)
{
try
(
Stream
<?
extends
R
>
result
=
mapper
.
apply
(
u
))
{
try
(
Stream
<?
extends
R
>
result
=
mapper
.
apply
(
u
))
{
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if
(
result
!=
null
)
{
if
(
result
!=
null
)
if
(!
cancellationRequestedCalled
)
{
result
.
sequential
().
forEach
(
downstream
);
result
.
sequential
().
forEach
(
downstream
);
}
else
{
Spliterator
<?
extends
R
>
s
=
result
.
sequential
().
spliterator
();
do
{
}
while
(!
downstream
.
cancellationRequested
()
&&
s
.
tryAdvance
(
downstream
));
}
}
}
}
}
}
@Override
public
boolean
cancellationRequested
()
{
// If this method is called then an operation within the stream
// pipeline is short-circuiting (see AbstractPipeline.copyInto).
// Note that we cannot differentiate between an upstream or
// downstream operation
cancellationRequestedCalled
=
true
;
return
downstream
.
cancellationRequested
();
}
};
};
}
}
};
};
...
@@ -278,13 +296,17 @@ abstract class ReferencePipeline<P_IN, P_OUT>
...
@@ -278,13 +296,17 @@ abstract class ReferencePipeline<P_IN, P_OUT>
@Override
@Override
public
final
IntStream
flatMapToInt
(
Function
<?
super
P_OUT
,
?
extends
IntStream
>
mapper
)
{
public
final
IntStream
flatMapToInt
(
Function
<?
super
P_OUT
,
?
extends
IntStream
>
mapper
)
{
Objects
.
requireNonNull
(
mapper
);
Objects
.
requireNonNull
(
mapper
);
// We can do better than this, by polling cancellationRequested when stream is infinite
return
new
IntPipeline
.
StatelessOp
<
P_OUT
>(
this
,
StreamShape
.
REFERENCE
,
return
new
IntPipeline
.
StatelessOp
<
P_OUT
>(
this
,
StreamShape
.
REFERENCE
,
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
@Override
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Integer
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Integer
>(
sink
)
{
// true if cancellationRequested() has been called
boolean
cancellationRequestedCalled
;
// cache the consumer to avoid creation on every accepted element
IntConsumer
downstreamAsInt
=
downstream:
:
accept
;
IntConsumer
downstreamAsInt
=
downstream:
:
accept
;
@Override
@Override
public
void
begin
(
long
size
)
{
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
downstream
.
begin
(-
1
);
...
@@ -293,11 +315,23 @@ abstract class ReferencePipeline<P_IN, P_OUT>
...
@@ -293,11 +315,23 @@ abstract class ReferencePipeline<P_IN, P_OUT>
@Override
@Override
public
void
accept
(
P_OUT
u
)
{
public
void
accept
(
P_OUT
u
)
{
try
(
IntStream
result
=
mapper
.
apply
(
u
))
{
try
(
IntStream
result
=
mapper
.
apply
(
u
))
{
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if
(
result
!=
null
)
{
if
(
result
!=
null
)
if
(!
cancellationRequestedCalled
)
{
result
.
sequential
().
forEach
(
downstreamAsInt
);
result
.
sequential
().
forEach
(
downstreamAsInt
);
}
else
{
Spliterator
.
OfInt
s
=
result
.
sequential
().
spliterator
();
do
{
}
while
(!
downstream
.
cancellationRequested
()
&&
s
.
tryAdvance
(
downstreamAsInt
));
}
}
}
}
}
}
@Override
public
boolean
cancellationRequested
()
{
cancellationRequestedCalled
=
true
;
return
downstream
.
cancellationRequested
();
}
};
};
}
}
};
};
...
@@ -306,13 +340,17 @@ abstract class ReferencePipeline<P_IN, P_OUT>
...
@@ -306,13 +340,17 @@ abstract class ReferencePipeline<P_IN, P_OUT>
@Override
@Override
public
final
DoubleStream
flatMapToDouble
(
Function
<?
super
P_OUT
,
?
extends
DoubleStream
>
mapper
)
{
public
final
DoubleStream
flatMapToDouble
(
Function
<?
super
P_OUT
,
?
extends
DoubleStream
>
mapper
)
{
Objects
.
requireNonNull
(
mapper
);
Objects
.
requireNonNull
(
mapper
);
// We can do better than this, by polling cancellationRequested when stream is infinite
return
new
DoublePipeline
.
StatelessOp
<
P_OUT
>(
this
,
StreamShape
.
REFERENCE
,
return
new
DoublePipeline
.
StatelessOp
<
P_OUT
>(
this
,
StreamShape
.
REFERENCE
,
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
@Override
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Double
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Double
>(
sink
)
{
// true if cancellationRequested() has been called
boolean
cancellationRequestedCalled
;
// cache the consumer to avoid creation on every accepted element
DoubleConsumer
downstreamAsDouble
=
downstream:
:
accept
;
DoubleConsumer
downstreamAsDouble
=
downstream:
:
accept
;
@Override
@Override
public
void
begin
(
long
size
)
{
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
downstream
.
begin
(-
1
);
...
@@ -321,11 +359,23 @@ abstract class ReferencePipeline<P_IN, P_OUT>
...
@@ -321,11 +359,23 @@ abstract class ReferencePipeline<P_IN, P_OUT>
@Override
@Override
public
void
accept
(
P_OUT
u
)
{
public
void
accept
(
P_OUT
u
)
{
try
(
DoubleStream
result
=
mapper
.
apply
(
u
))
{
try
(
DoubleStream
result
=
mapper
.
apply
(
u
))
{
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if
(
result
!=
null
)
{
if
(
result
!=
null
)
if
(!
cancellationRequestedCalled
)
{
result
.
sequential
().
forEach
(
downstreamAsDouble
);
result
.
sequential
().
forEach
(
downstreamAsDouble
);
}
else
{
Spliterator
.
OfDouble
s
=
result
.
sequential
().
spliterator
();
do
{
}
while
(!
downstream
.
cancellationRequested
()
&&
s
.
tryAdvance
(
downstreamAsDouble
));
}
}
}
}
}
}
@Override
public
boolean
cancellationRequested
()
{
cancellationRequestedCalled
=
true
;
return
downstream
.
cancellationRequested
();
}
};
};
}
}
};
};
...
@@ -340,7 +390,12 @@ abstract class ReferencePipeline<P_IN, P_OUT>
...
@@ -340,7 +390,12 @@ abstract class ReferencePipeline<P_IN, P_OUT>
@Override
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Long
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Long
>(
sink
)
{
// true if cancellationRequested() has been called
boolean
cancellationRequestedCalled
;
// cache the consumer to avoid creation on every accepted element
LongConsumer
downstreamAsLong
=
downstream:
:
accept
;
LongConsumer
downstreamAsLong
=
downstream:
:
accept
;
@Override
@Override
public
void
begin
(
long
size
)
{
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
downstream
.
begin
(-
1
);
...
@@ -349,11 +404,23 @@ abstract class ReferencePipeline<P_IN, P_OUT>
...
@@ -349,11 +404,23 @@ abstract class ReferencePipeline<P_IN, P_OUT>
@Override
@Override
public
void
accept
(
P_OUT
u
)
{
public
void
accept
(
P_OUT
u
)
{
try
(
LongStream
result
=
mapper
.
apply
(
u
))
{
try
(
LongStream
result
=
mapper
.
apply
(
u
))
{
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if
(
result
!=
null
)
{
if
(
result
!=
null
)
if
(!
cancellationRequestedCalled
)
{
result
.
sequential
().
forEach
(
downstreamAsLong
);
result
.
sequential
().
forEach
(
downstreamAsLong
);
}
else
{
Spliterator
.
OfLong
s
=
result
.
sequential
().
spliterator
();
do
{
}
while
(!
downstream
.
cancellationRequested
()
&&
s
.
tryAdvance
(
downstreamAsLong
));
}
}
}
}
}
}
@Override
public
boolean
cancellationRequested
()
{
cancellationRequestedCalled
=
true
;
return
downstream
.
cancellationRequested
();
}
};
};
}
}
};
};
...
...
src/share/classes/java/util/stream/SortedOps.java
浏览文件 @
da485e25
/*
/*
* Copyright (c) 2012, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -304,7 +304,8 @@ final class SortedOps {
...
@@ -304,7 +304,8 @@ final class SortedOps {
private
static
abstract
class
AbstractRefSortingSink
<
T
>
extends
Sink
.
ChainedReference
<
T
,
T
>
{
private
static
abstract
class
AbstractRefSortingSink
<
T
>
extends
Sink
.
ChainedReference
<
T
,
T
>
{
protected
final
Comparator
<?
super
T
>
comparator
;
protected
final
Comparator
<?
super
T
>
comparator
;
// @@@ could be a lazy final value, if/when support is added
// @@@ could be a lazy final value, if/when support is added
protected
boolean
cancellationWasRequested
;
// true if cancellationRequested() has been called
protected
boolean
cancellationRequestedCalled
;
AbstractRefSortingSink
(
Sink
<?
super
T
>
downstream
,
Comparator
<?
super
T
>
comparator
)
{
AbstractRefSortingSink
(
Sink
<?
super
T
>
downstream
,
Comparator
<?
super
T
>
comparator
)
{
super
(
downstream
);
super
(
downstream
);
...
@@ -319,7 +320,11 @@ final class SortedOps {
...
@@ -319,7 +320,11 @@ final class SortedOps {
*/
*/
@Override
@Override
public
final
boolean
cancellationRequested
()
{
public
final
boolean
cancellationRequested
()
{
cancellationWasRequested
=
true
;
// If this method is called then an operation within the stream
// pipeline is short-circuiting (see AbstractPipeline.copyInto).
// Note that we cannot differentiate between an upstream or
// downstream operation
cancellationRequestedCalled
=
true
;
return
false
;
return
false
;
}
}
}
}
...
@@ -347,7 +352,7 @@ final class SortedOps {
...
@@ -347,7 +352,7 @@ final class SortedOps {
public
void
end
()
{
public
void
end
()
{
Arrays
.
sort
(
array
,
0
,
offset
,
comparator
);
Arrays
.
sort
(
array
,
0
,
offset
,
comparator
);
downstream
.
begin
(
offset
);
downstream
.
begin
(
offset
);
if
(!
cancellation
WasRequest
ed
)
{
if
(!
cancellation
RequestedCall
ed
)
{
for
(
int
i
=
0
;
i
<
offset
;
i
++)
for
(
int
i
=
0
;
i
<
offset
;
i
++)
downstream
.
accept
(
array
[
i
]);
downstream
.
accept
(
array
[
i
]);
}
}
...
@@ -386,7 +391,7 @@ final class SortedOps {
...
@@ -386,7 +391,7 @@ final class SortedOps {
public
void
end
()
{
public
void
end
()
{
list
.
sort
(
comparator
);
list
.
sort
(
comparator
);
downstream
.
begin
(
list
.
size
());
downstream
.
begin
(
list
.
size
());
if
(!
cancellation
WasRequest
ed
)
{
if
(!
cancellation
RequestedCall
ed
)
{
list
.
forEach
(
downstream:
:
accept
);
list
.
forEach
(
downstream:
:
accept
);
}
}
else
{
else
{
...
@@ -409,7 +414,8 @@ final class SortedOps {
...
@@ -409,7 +414,8 @@ final class SortedOps {
* Abstract {@link Sink} for implementing sort on int streams.
* Abstract {@link Sink} for implementing sort on int streams.
*/
*/
private
static
abstract
class
AbstractIntSortingSink
extends
Sink
.
ChainedInt
<
Integer
>
{
private
static
abstract
class
AbstractIntSortingSink
extends
Sink
.
ChainedInt
<
Integer
>
{
protected
boolean
cancellationWasRequested
;
// true if cancellationRequested() has been called
protected
boolean
cancellationRequestedCalled
;
AbstractIntSortingSink
(
Sink
<?
super
Integer
>
downstream
)
{
AbstractIntSortingSink
(
Sink
<?
super
Integer
>
downstream
)
{
super
(
downstream
);
super
(
downstream
);
...
@@ -417,7 +423,7 @@ final class SortedOps {
...
@@ -417,7 +423,7 @@ final class SortedOps {
@Override
@Override
public
final
boolean
cancellationRequested
()
{
public
final
boolean
cancellationRequested
()
{
cancellation
WasRequest
ed
=
true
;
cancellation
RequestedCall
ed
=
true
;
return
false
;
return
false
;
}
}
}
}
...
@@ -444,7 +450,7 @@ final class SortedOps {
...
@@ -444,7 +450,7 @@ final class SortedOps {
public
void
end
()
{
public
void
end
()
{
Arrays
.
sort
(
array
,
0
,
offset
);
Arrays
.
sort
(
array
,
0
,
offset
);
downstream
.
begin
(
offset
);
downstream
.
begin
(
offset
);
if
(!
cancellation
WasRequest
ed
)
{
if
(!
cancellation
RequestedCall
ed
)
{
for
(
int
i
=
0
;
i
<
offset
;
i
++)
for
(
int
i
=
0
;
i
<
offset
;
i
++)
downstream
.
accept
(
array
[
i
]);
downstream
.
accept
(
array
[
i
]);
}
}
...
@@ -484,7 +490,7 @@ final class SortedOps {
...
@@ -484,7 +490,7 @@ final class SortedOps {
int
[]
ints
=
b
.
asPrimitiveArray
();
int
[]
ints
=
b
.
asPrimitiveArray
();
Arrays
.
sort
(
ints
);
Arrays
.
sort
(
ints
);
downstream
.
begin
(
ints
.
length
);
downstream
.
begin
(
ints
.
length
);
if
(!
cancellation
WasRequest
ed
)
{
if
(!
cancellation
RequestedCall
ed
)
{
for
(
int
anInt
:
ints
)
for
(
int
anInt
:
ints
)
downstream
.
accept
(
anInt
);
downstream
.
accept
(
anInt
);
}
}
...
@@ -507,7 +513,8 @@ final class SortedOps {
...
@@ -507,7 +513,8 @@ final class SortedOps {
* Abstract {@link Sink} for implementing sort on long streams.
* Abstract {@link Sink} for implementing sort on long streams.
*/
*/
private
static
abstract
class
AbstractLongSortingSink
extends
Sink
.
ChainedLong
<
Long
>
{
private
static
abstract
class
AbstractLongSortingSink
extends
Sink
.
ChainedLong
<
Long
>
{
protected
boolean
cancellationWasRequested
;
// true if cancellationRequested() has been called
protected
boolean
cancellationRequestedCalled
;
AbstractLongSortingSink
(
Sink
<?
super
Long
>
downstream
)
{
AbstractLongSortingSink
(
Sink
<?
super
Long
>
downstream
)
{
super
(
downstream
);
super
(
downstream
);
...
@@ -515,7 +522,7 @@ final class SortedOps {
...
@@ -515,7 +522,7 @@ final class SortedOps {
@Override
@Override
public
final
boolean
cancellationRequested
()
{
public
final
boolean
cancellationRequested
()
{
cancellation
WasRequest
ed
=
true
;
cancellation
RequestedCall
ed
=
true
;
return
false
;
return
false
;
}
}
}
}
...
@@ -542,7 +549,7 @@ final class SortedOps {
...
@@ -542,7 +549,7 @@ final class SortedOps {
public
void
end
()
{
public
void
end
()
{
Arrays
.
sort
(
array
,
0
,
offset
);
Arrays
.
sort
(
array
,
0
,
offset
);
downstream
.
begin
(
offset
);
downstream
.
begin
(
offset
);
if
(!
cancellation
WasRequest
ed
)
{
if
(!
cancellation
RequestedCall
ed
)
{
for
(
int
i
=
0
;
i
<
offset
;
i
++)
for
(
int
i
=
0
;
i
<
offset
;
i
++)
downstream
.
accept
(
array
[
i
]);
downstream
.
accept
(
array
[
i
]);
}
}
...
@@ -582,7 +589,7 @@ final class SortedOps {
...
@@ -582,7 +589,7 @@ final class SortedOps {
long
[]
longs
=
b
.
asPrimitiveArray
();
long
[]
longs
=
b
.
asPrimitiveArray
();
Arrays
.
sort
(
longs
);
Arrays
.
sort
(
longs
);
downstream
.
begin
(
longs
.
length
);
downstream
.
begin
(
longs
.
length
);
if
(!
cancellation
WasRequest
ed
)
{
if
(!
cancellation
RequestedCall
ed
)
{
for
(
long
aLong
:
longs
)
for
(
long
aLong
:
longs
)
downstream
.
accept
(
aLong
);
downstream
.
accept
(
aLong
);
}
}
...
@@ -605,7 +612,8 @@ final class SortedOps {
...
@@ -605,7 +612,8 @@ final class SortedOps {
* Abstract {@link Sink} for implementing sort on long streams.
* Abstract {@link Sink} for implementing sort on long streams.
*/
*/
private
static
abstract
class
AbstractDoubleSortingSink
extends
Sink
.
ChainedDouble
<
Double
>
{
private
static
abstract
class
AbstractDoubleSortingSink
extends
Sink
.
ChainedDouble
<
Double
>
{
protected
boolean
cancellationWasRequested
;
// true if cancellationRequested() has been called
protected
boolean
cancellationRequestedCalled
;
AbstractDoubleSortingSink
(
Sink
<?
super
Double
>
downstream
)
{
AbstractDoubleSortingSink
(
Sink
<?
super
Double
>
downstream
)
{
super
(
downstream
);
super
(
downstream
);
...
@@ -613,7 +621,7 @@ final class SortedOps {
...
@@ -613,7 +621,7 @@ final class SortedOps {
@Override
@Override
public
final
boolean
cancellationRequested
()
{
public
final
boolean
cancellationRequested
()
{
cancellation
WasRequest
ed
=
true
;
cancellation
RequestedCall
ed
=
true
;
return
false
;
return
false
;
}
}
}
}
...
@@ -640,7 +648,7 @@ final class SortedOps {
...
@@ -640,7 +648,7 @@ final class SortedOps {
public
void
end
()
{
public
void
end
()
{
Arrays
.
sort
(
array
,
0
,
offset
);
Arrays
.
sort
(
array
,
0
,
offset
);
downstream
.
begin
(
offset
);
downstream
.
begin
(
offset
);
if
(!
cancellation
WasRequest
ed
)
{
if
(!
cancellation
RequestedCall
ed
)
{
for
(
int
i
=
0
;
i
<
offset
;
i
++)
for
(
int
i
=
0
;
i
<
offset
;
i
++)
downstream
.
accept
(
array
[
i
]);
downstream
.
accept
(
array
[
i
]);
}
}
...
@@ -680,7 +688,7 @@ final class SortedOps {
...
@@ -680,7 +688,7 @@ final class SortedOps {
double
[]
doubles
=
b
.
asPrimitiveArray
();
double
[]
doubles
=
b
.
asPrimitiveArray
();
Arrays
.
sort
(
doubles
);
Arrays
.
sort
(
doubles
);
downstream
.
begin
(
doubles
.
length
);
downstream
.
begin
(
doubles
.
length
);
if
(!
cancellation
WasRequest
ed
)
{
if
(!
cancellation
RequestedCall
ed
)
{
for
(
double
aDouble
:
doubles
)
for
(
double
aDouble
:
doubles
)
downstream
.
accept
(
aDouble
);
downstream
.
accept
(
aDouble
);
}
}
...
...
test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java
浏览文件 @
da485e25
/*
/*
* Copyright (c) 2012, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
/*
/*
* @test
* @test
* @summary flat-map operations
* @summary flat-map operations
* @bug 8044047 8076458
* @bug 8044047 8076458
8075939
*/
*/
package
org.openjdk.tests.java.util.stream
;
package
org.openjdk.tests.java.util.stream
;
...
@@ -36,6 +36,7 @@ import java.util.Collection;
...
@@ -36,6 +36,7 @@ import java.util.Collection;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.function.Function
;
import
java.util.function.Function
;
import
java.util.stream.*
;
import
java.util.stream.*
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
static
java
.
util
.
stream
.
LambdaTestHelpers
.*;
import
static
java
.
util
.
stream
.
LambdaTestHelpers
.*;
import
static
java
.
util
.
stream
.
ThowableHelper
.
checkNPE
;
import
static
java
.
util
.
stream
.
ThowableHelper
.
checkNPE
;
...
@@ -43,6 +44,7 @@ import static java.util.stream.ThowableHelper.checkNPE;
...
@@ -43,6 +44,7 @@ import static java.util.stream.ThowableHelper.checkNPE;
@Test
@Test
public
class
FlatMapOpTest
extends
OpTestCase
{
public
class
FlatMapOpTest
extends
OpTestCase
{
@Test
public
void
testNullMapper
()
{
public
void
testNullMapper
()
{
checkNPE
(()
->
Stream
.
of
(
1
).
flatMap
(
null
));
checkNPE
(()
->
Stream
.
of
(
1
).
flatMap
(
null
));
checkNPE
(()
->
IntStream
.
of
(
1
).
flatMap
(
null
));
checkNPE
(()
->
IntStream
.
of
(
1
).
flatMap
(
null
));
...
@@ -53,6 +55,7 @@ public class FlatMapOpTest extends OpTestCase {
...
@@ -53,6 +55,7 @@ public class FlatMapOpTest extends OpTestCase {
static
final
Function
<
Integer
,
Stream
<
Integer
>>
integerRangeMapper
static
final
Function
<
Integer
,
Stream
<
Integer
>>
integerRangeMapper
=
e
->
IntStream
.
range
(
0
,
e
).
boxed
();
=
e
->
IntStream
.
range
(
0
,
e
).
boxed
();
@Test
public
void
testFlatMap
()
{
public
void
testFlatMap
()
{
String
[]
stringsArray
=
{
"hello"
,
"there"
,
""
,
"yada"
};
String
[]
stringsArray
=
{
"hello"
,
"there"
,
""
,
"yada"
};
Stream
<
String
>
strings
=
Arrays
.
asList
(
stringsArray
).
stream
();
Stream
<
String
>
strings
=
Arrays
.
asList
(
stringsArray
).
stream
();
...
@@ -85,11 +88,24 @@ public class FlatMapOpTest extends OpTestCase {
...
@@ -85,11 +88,24 @@ public class FlatMapOpTest extends OpTestCase {
exerciseOps
(
data
,
s
->
s
.
flatMap
((
Integer
e
)
->
IntStream
.
range
(
0
,
e
).
boxed
().
limit
(
10
)));
exerciseOps
(
data
,
s
->
s
.
flatMap
((
Integer
e
)
->
IntStream
.
range
(
0
,
e
).
boxed
().
limit
(
10
)));
}
}
@Test
public
void
testOpsShortCircuit
()
{
AtomicInteger
count
=
new
AtomicInteger
();
Stream
.
of
(
0
).
flatMap
(
i
->
IntStream
.
range
(
0
,
100
).
boxed
()).
peek
(
i
->
count
.
incrementAndGet
()).
limit
(
10
).
toArray
();
assertEquals
(
count
.
get
(),
10
);
}
//
//
@Test
(
dataProvider
=
"IntStreamTestData"
,
dataProviderClass
=
IntStreamTestDataProvider
.
class
)
@Test
(
dataProvider
=
"IntStreamTestData"
,
dataProviderClass
=
IntStreamTestDataProvider
.
class
)
public
void
testIntOps
(
String
name
,
TestData
.
OfInt
data
)
{
public
void
testIntOps
(
String
name
,
TestData
.
OfInt
data
)
{
Collection
<
Integer
>
result
=
exerciseOps
(
data
,
s
->
s
.
flatMap
(
i
->
Collections
.
singleton
(
i
).
stream
().
mapToInt
(
j
->
j
)));
Collection
<
Integer
>
result
=
exerciseOps
(
data
,
s
->
s
.
flatMap
(
IntStream:
:
of
));
assertEquals
(
data
.
size
(),
result
.
size
());
assertContents
(
data
,
result
);
result
=
exerciseOps
(
data
,
s
->
s
.
boxed
().
flatMapToInt
(
IntStream:
:
of
));
assertEquals
(
data
.
size
(),
result
.
size
());
assertEquals
(
data
.
size
(),
result
.
size
());
assertContents
(
data
,
result
);
assertContents
(
data
,
result
);
...
@@ -101,13 +117,35 @@ public class FlatMapOpTest extends OpTestCase {
...
@@ -101,13 +117,35 @@ public class FlatMapOpTest extends OpTestCase {
public
void
testIntOpsX
(
String
name
,
TestData
.
OfInt
data
)
{
public
void
testIntOpsX
(
String
name
,
TestData
.
OfInt
data
)
{
exerciseOps
(
data
,
s
->
s
.
flatMap
(
e
->
IntStream
.
range
(
0
,
e
)));
exerciseOps
(
data
,
s
->
s
.
flatMap
(
e
->
IntStream
.
range
(
0
,
e
)));
exerciseOps
(
data
,
s
->
s
.
flatMap
(
e
->
IntStream
.
range
(
0
,
e
).
limit
(
10
)));
exerciseOps
(
data
,
s
->
s
.
flatMap
(
e
->
IntStream
.
range
(
0
,
e
).
limit
(
10
)));
exerciseOps
(
data
,
s
->
s
.
boxed
().
flatMapToInt
(
e
->
IntStream
.
range
(
0
,
e
)));
exerciseOps
(
data
,
s
->
s
.
boxed
().
flatMapToInt
(
e
->
IntStream
.
range
(
0
,
e
).
limit
(
10
)));
}
@Test
public
void
testIntOpsShortCircuit
()
{
AtomicInteger
count
=
new
AtomicInteger
();
IntStream
.
of
(
0
).
flatMap
(
i
->
IntStream
.
range
(
0
,
100
)).
peek
(
i
->
count
.
incrementAndGet
()).
limit
(
10
).
toArray
();
assertEquals
(
count
.
get
(),
10
);
count
.
set
(
0
);
Stream
.
of
(
0
).
flatMapToInt
(
i
->
IntStream
.
range
(
0
,
100
)).
peek
(
i
->
count
.
incrementAndGet
()).
limit
(
10
).
toArray
();
assertEquals
(
count
.
get
(),
10
);
}
}
//
//
@Test
(
dataProvider
=
"LongStreamTestData"
,
dataProviderClass
=
LongStreamTestDataProvider
.
class
)
@Test
(
dataProvider
=
"LongStreamTestData"
,
dataProviderClass
=
LongStreamTestDataProvider
.
class
)
public
void
testLongOps
(
String
name
,
TestData
.
OfLong
data
)
{
public
void
testLongOps
(
String
name
,
TestData
.
OfLong
data
)
{
Collection
<
Long
>
result
=
exerciseOps
(
data
,
s
->
s
.
flatMap
(
i
->
Collections
.
singleton
(
i
).
stream
().
mapToLong
(
j
->
j
)));
Collection
<
Long
>
result
=
exerciseOps
(
data
,
s
->
s
.
flatMap
(
LongStream:
:
of
));
assertEquals
(
data
.
size
(),
result
.
size
());
assertContents
(
data
,
result
);
result
=
exerciseOps
(
data
,
s
->
s
.
boxed
().
flatMapToLong
(
LongStream:
:
of
));
assertEquals
(
data
.
size
(),
result
.
size
());
assertEquals
(
data
.
size
(),
result
.
size
());
assertContents
(
data
,
result
);
assertContents
(
data
,
result
);
...
@@ -121,11 +159,30 @@ public class FlatMapOpTest extends OpTestCase {
...
@@ -121,11 +159,30 @@ public class FlatMapOpTest extends OpTestCase {
exerciseOps
(
data
,
s
->
s
.
flatMap
(
e
->
LongStream
.
range
(
0
,
e
).
limit
(
10
)));
exerciseOps
(
data
,
s
->
s
.
flatMap
(
e
->
LongStream
.
range
(
0
,
e
).
limit
(
10
)));
}
}
@Test
public
void
testLongOpsShortCircuit
()
{
AtomicInteger
count
=
new
AtomicInteger
();
LongStream
.
of
(
0
).
flatMap
(
i
->
LongStream
.
range
(
0
,
100
)).
peek
(
i
->
count
.
incrementAndGet
()).
limit
(
10
).
toArray
();
assertEquals
(
count
.
get
(),
10
);
count
.
set
(
0
);
Stream
.
of
(
0
).
flatMapToLong
(
i
->
LongStream
.
range
(
0
,
100
)).
peek
(
i
->
count
.
incrementAndGet
()).
limit
(
10
).
toArray
();
assertEquals
(
count
.
get
(),
10
);
}
//
//
@Test
(
dataProvider
=
"DoubleStreamTestData"
,
dataProviderClass
=
DoubleStreamTestDataProvider
.
class
)
@Test
(
dataProvider
=
"DoubleStreamTestData"
,
dataProviderClass
=
DoubleStreamTestDataProvider
.
class
)
public
void
testDoubleOps
(
String
name
,
TestData
.
OfDouble
data
)
{
public
void
testDoubleOps
(
String
name
,
TestData
.
OfDouble
data
)
{
Collection
<
Double
>
result
=
exerciseOps
(
data
,
s
->
s
.
flatMap
(
i
->
Collections
.
singleton
(
i
).
stream
().
mapToDouble
(
j
->
j
)));
Collection
<
Double
>
result
=
exerciseOps
(
data
,
s
->
s
.
flatMap
(
DoubleStream:
:
of
));
assertEquals
(
data
.
size
(),
result
.
size
());
assertContents
(
data
,
result
);
result
=
exerciseOps
(
data
,
s
->
s
.
boxed
().
flatMapToDouble
(
DoubleStream:
:
of
));
assertEquals
(
data
.
size
(),
result
.
size
());
assertEquals
(
data
.
size
(),
result
.
size
());
assertContents
(
data
,
result
);
assertContents
(
data
,
result
);
...
@@ -138,4 +195,19 @@ public class FlatMapOpTest extends OpTestCase {
...
@@ -138,4 +195,19 @@ public class FlatMapOpTest extends OpTestCase {
exerciseOps
(
data
,
s
->
s
.
flatMap
(
e
->
IntStream
.
range
(
0
,
(
int
)
e
).
asDoubleStream
()));
exerciseOps
(
data
,
s
->
s
.
flatMap
(
e
->
IntStream
.
range
(
0
,
(
int
)
e
).
asDoubleStream
()));
exerciseOps
(
data
,
s
->
s
.
flatMap
(
e
->
IntStream
.
range
(
0
,
(
int
)
e
).
limit
(
10
).
asDoubleStream
()));
exerciseOps
(
data
,
s
->
s
.
flatMap
(
e
->
IntStream
.
range
(
0
,
(
int
)
e
).
limit
(
10
).
asDoubleStream
()));
}
}
@Test
public
void
testDoubleOpsShortCircuit
()
{
AtomicInteger
count
=
new
AtomicInteger
();
DoubleStream
.
of
(
0
).
flatMap
(
i
->
IntStream
.
range
(
0
,
100
).
asDoubleStream
()).
peek
(
i
->
count
.
incrementAndGet
()).
limit
(
10
).
toArray
();
assertEquals
(
count
.
get
(),
10
);
count
.
set
(
0
);
Stream
.
of
(
0
).
flatMapToDouble
(
i
->
IntStream
.
range
(
0
,
100
).
asDoubleStream
()).
peek
(
i
->
count
.
incrementAndGet
()).
limit
(
10
).
toArray
();
assertEquals
(
count
.
get
(),
10
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录