一、Optional
Java应用中最常见的bug就是空值异常。在Java 8之前,Google Guava引入了Optionals类来解决NullPointerException,从而避免源码被各种null检查污染,以便开发者写出更加整洁的代码。Java 8也将Optional加入了官方库。
Optional仅仅是一个容易:存放T类型的值或者null。它提供了一些有用的接口来避免显式的null检查。
API:
Modifier and Type | Method and Description |
---|---|
static <T> Optional<T> |
empty() 返回一个空的 |
boolean |
equals(Object obj) 指示某个其他对象是否等于此可选项。 |
Optional<T> |
filter(Predicate<? super T> predicate) 如果一个值存在,并且该值给定的谓词相匹配时,返回一个 |
<U> Optional<U> |
flatMap(Function<? super T,Optional<U>> mapper) 如果一个值存在,应用提供的 |
T |
get() 如果 |
int |
hashCode() 返回当前值的哈希码值(如果有的话),如果没有值,则返回0(零)。 |
void |
ifPresent(Consumer<? super T> consumer) 如果存在值,则使用该值调用指定的消费者,否则不执行任何操作。 |
boolean |
isPresent() 返回 |
<U> Optional<U> |
map(Function<? super T,? extends U> mapper) 如果存在一个值,则应用提供的映射函数,如果结果不为空,则返回一个 |
static <T> Optional<T> |
of(T value) 返回具有 |
static <T> Optional<T> |
ofNullable(T value) 返回一个 |
T |
orElse(T other) 返回值如果存在,否则返回 |
T |
orElseGet(Supplier<? extends T> other) 返回值(如果存在),否则调用 |
<X extends Throwable> |
orElseThrow(Supplier<? extends X> exceptionSupplier) 返回包含的值(如果存在),否则抛出由提供的供应商创建的异常。 |
String |
toString() 返回此可选的非空字符串表示,适用于调试。 |
二、Stream
参考:
http://blog.csdn.net/u010425776/article/details/52344425
http://blog.csdn.net/u010425776/article/details/52346644
API:
Modifier and Type | Method and Description |
---|---|
boolean |
allMatch(Predicate<? super T> predicate) 返回此流的所有元素是否与提供的谓词匹配。 |
boolean |
anyMatch(Predicate<? super T> predicate) 返回此流的任何元素是否与提供的谓词匹配。 |
static <T> Stream.Builder<T> |
builder() 返回一个 |
<R,A> R |
collect(Collector<? super T,A,R> collector) 使用 Collector对此流的元素执行 mutable reduction |
<R> R |
collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner) 对此流的元素执行 mutable reduction操作。 |
static <T> Stream<T> |
concat(Stream<? extends T> a, Stream<? extends T> b) 创建一个懒惰连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。 |
long |
count() 返回此流中的元素数。 |
Stream<T> |
distinct() 返回由该流的不同元素(根据 Object.equals(Object) )组成的流。 |
static <T> Stream<T> |
empty() 返回一个空的顺序 |
Stream<T> |
filter(Predicate<? super T> predicate) 返回由与此给定谓词匹配的此流的元素组成的流。 |
Optional<T> |
findAny() 返回描述流的一些元素的 |
Optional<T> |
findFirst() 返回描述此流的第一个元素的 |
<R> Stream<R> |
flatMap(Function<? super T,? extends Stream<? extends R>> mapper) 返回由通过将提供的映射函数应用于每个元素而产生的映射流的内容来替换该流的每个元素的结果的流。 |
DoubleStream |
flatMapToDouble(Function<? super T,? extends DoubleStream> mapper) 返回一个 |
IntStream |
flatMapToInt(Function<? super T,? extends IntStream> mapper) 返回一个 |
LongStream |
flatMapToLong(Function<? super T,? extends LongStream> mapper) 返回一个 |
void |
forEach(Consumer<? super T> action) 对此流的每个元素执行操作。 |
void |
forEachOrdered(Consumer<? super T> action) 如果流具有定义的遇到顺序,则以流的遇到顺序对该流的每个元素执行操作。 |
static <T> Stream<T> |
generate(Supplier<T> s) 返回无限顺序无序流,其中每个元素由提供的 |
static <T> Stream<T> |
iterate(T seed, UnaryOperator<T> f) 返回有序无限连续 |
Stream<T> |
limit(long maxSize) 返回由此流的元素组成的流,截短长度不能超过 |
<R> Stream<R> |
map(Function<? super T,? extends R> mapper) 返回由给定函数应用于此流的元素的结果组成的流。 |
DoubleStream |
mapToDouble(ToDoubleFunction<? super T> mapper) 返回一个 |
IntStream |
mapToInt(ToIntFunction<? super T> mapper) 返回一个 |
LongStream |
mapToLong(ToLongFunction<? super T> mapper) 返回一个 |
Optional<T> |
max(Comparator<? super T> comparator) 根据提供的 |
Optional<T> |
min(Comparator<? super T> comparator) 根据提供的 |
boolean |
noneMatch(Predicate<? super T> predicate) 返回此流的元素是否与提供的谓词匹配。 |
static <T> Stream<T> |
of(T... values) 返回其元素是指定值的顺序排序流。 |
static <T> Stream<T> |
of(T t) 返回包含单个元素的顺序 |
Stream<T> |
peek(Consumer<? super T> action) 返回由该流的元素组成的流,另外在从生成的流中消耗元素时对每个元素执行提供的操作。 |
Optional<T> |
reduce(BinaryOperator<T> accumulator) 使用 associative累积函数对此流的元素执行 reduction ,并返回描述减小值的 |
T |
reduce(T identity, BinaryOperator<T> accumulator) 使用提供的身份值和 associative累积功能对此流的元素执行 reduction ,并返回减小的值。 |
<U> U |
reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner) 执行 reduction在此流中的元素,使用所提供的身份,积累和组合功能。 |
Stream<T> |
skip(long n) 在丢弃流的第一个 |
Stream<T> |
sorted() 返回由此流的元素组成的流,根据自然顺序排序。 |
Stream<T> |
sorted(Comparator<? super T> comparator) 返回由该流的元素组成的流,根据提供的 |
Object[] |
toArray() 返回一个包含此流的元素的数组。 |
<A> A[] |
toArray(IntFunction<A[]> generator) 使用提供的 |
三、Collectors
API:
Modifier and Type | Method and Description |
---|---|
static <T> Collector<T,?,Double> |
averagingDouble(ToDoubleFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,Double> |
averagingInt(ToIntFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,Double> |
averagingLong(ToLongFunction<? super T> mapper) 返回一个 |
static <T,A,R,RR> Collector<T,A,RR> |
collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher) 适应 |
static <T> Collector<T,?,Long> |
counting() 返回 |
static <T,K> Collector<T,?,Map<K,List<T>>> |
groupingBy(Function<? super T,? extends K> classifier) 返回 |
static <T,K,A,D> Collector<T,?,Map<K,D>> |
groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream) 返回 |
static <T,K,D,A,M extends Map<K,D>> |
groupingBy(Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream) 返回 |
static <T,K> Collector<T,?,ConcurrentMap<K,List<T>>> |
groupingByConcurrent(Function<? super T,? extends K> classifier) 返回一个并发 |
static <T,K,A,D> Collector<T,?,ConcurrentMap<K,D>> |
groupingByConcurrent(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream) 返回一个并发 |
static <T,K,A,D,M extends ConcurrentMap<K,D>> |
groupingByConcurrent(Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream) 返回一个并发 |
static Collector<CharSequence,?,String> |
joining() 返回一个 |
static Collector<CharSequence,?,String> |
joining(CharSequence delimiter) 返回一个 |
static Collector<CharSequence,?,String> |
joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) 返回一个 |
static <T,U,A,R> Collector<T,?,R> |
mapping(Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream) 适应一个 |
static <T> Collector<T,?,Optional<T>> |
maxBy(Comparator<? super T> comparator) 返回一个 |
static <T> Collector<T,?,Optional<T>> |
minBy(Comparator<? super T> comparator) 返回一个 |
static <T> Collector<T,?,Map<Boolean,List<T>>> |
partitioningBy(Predicate<? super T> predicate) 返回一个 |
static <T,D,A> Collector<T,?,Map<Boolean,D>> |
partitioningBy(Predicate<? super T> predicate, Collector<? super T,A,D> downstream) 返回一个 |
static <T> Collector<T,?,Optional<T>> |
reducing(BinaryOperator<T> op) 返回一个 |
static <T> Collector<T,?,T> |
reducing(T identity, BinaryOperator<T> op) 返回 |
static <T,U> Collector<T,?,U> |
reducing(U identity, Function<? super T,? extends U> mapper, BinaryOperator<U> op) 返回一个 |
static <T> Collector<T,?,DoubleSummaryStatistics> |
summarizingDouble(ToDoubleFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,IntSummaryStatistics> |
summarizingInt(ToIntFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,LongSummaryStatistics> |
summarizingLong(ToLongFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,Double> |
summingDouble(ToDoubleFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,Integer> |
summingInt(ToIntFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,Long> |
summingLong(ToLongFunction<? super T> mapper) 返回一个 |
static <T,C extends Collection<T>> |
toCollection(Supplier<C> collectionFactory) 返回一个 |
static <T,K,U> Collector<T,?,ConcurrentMap<K,U>> |
toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper) 返回一个并发的 |
static <T,K,U> Collector<T,?,ConcurrentMap<K,U>> |
toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction) 返回一个并发的 |
static <T,K,U,M extends ConcurrentMap<K,U>> |
toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier) 返回一个并发的 |
static <T> Collector<T,?,List<T>> |
toList() 返回一个 |
static <T,K,U> Collector<T,?,Map<K,U>> |
toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper) 返回一个 |
static <T,K,U> Collector<T,?,Map<K,U>> |
toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction) 返回一个 |
static <T,K,U,M extends Map<K,U>> |
toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier) 返回一个 |
static <T> Collector<T,?,Set<T>> |
toSet() 返回一个 |
工作中应用:
注:这个项目微服务架构使用dubbo
一、转换前数据结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
@XmlRootElement
@XmlAccessorType
(XmlAccessType.FIELD)
public
class
GeneTreeList
extends
ResponseBase {
@XmlElements
({
@XmlElement
(
name =
"tree"
,
type = GeneTree.
class
)})
private
List<GeneTree> treeList =
new
ArrayList();
public
GeneTreeList() {
}
public
List<GeneTree> getTreeList() {
return
this
.treeList;
}
public
void
setTreeList(List<GeneTree> treeList) {
this
.treeList = treeList;
}
}
@XmlRootElement
@XmlAccessorType
(XmlAccessType.FIELD)
public
class
GeneTree
extends
ResponseBase {
@XmlAttribute
private
int
portalId;
@XmlAttribute
private
int
parentTreeId;
@XmlAttribute
private
int
treeId;
@XmlAttribute
private
int
treeType;
@XmlAttribute
private
int
layer;
@XmlAttribute
private
int
order;
private
String treeName;
private
boolean
isLeaf;
private
String template;
private
int
retrieveId;
private
int
filmCount;
private
String icon =
""
;
private
String backgroundImg =
""
;
private
String cpid =
""
;
private
String copyright =
""
;
private
int
movieLimitCount;
private
int
movieAuditCount;
private
String moviePosterLimit =
""
;
private
Date updatetime;
private
Date createtime;
@XmlElements
({
@XmlElement
(
name =
"label"
,
type = GeneTreeLabel.
class
)})
private
List<GeneTreeLabel> labels =
new
ArrayList();
public
GeneTree() {
}
//get/set方法
。。。。。。
}
@XmlRootElement
@XmlAccessorType
(XmlAccessType.FIELD)
public
class
GeneTreeLabel
implements
Serializable {
@XmlAttribute
private
int
typeId;
@XmlAttribute
private
String typeName =
""
;
@XmlAttribute
private
int
labelId;
@XmlAttribute
private
String labelName =
""
;
public
GeneTreeLabel() {
}
}
|
二、定义转换后数据结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
@XmlRootElement
@XmlAccessorType
(XmlAccessType.FIELD)
public
class
LabelList
extends
ResponseBase {
@XmlElements
({
@XmlElement
(
name =
"Child"
,
type = OutChild.
class
)})
private
List<OutChild> childs =
new
ArrayList();
public
LabelList(){}
public
List<OutChild> getChilds() {
return
childs;
}
public
void
setChilds(List<OutChild> childs) {
this
.childs = childs;
}
}
@XmlRootElement
@XmlAccessorType
(XmlAccessType.FIELD)
public
class
OutChild
extends
ResponseBase {
@XmlAttribute
private
String typeName;
@XmlAttribute
private
int
typeId;
@XmlElements
({
@XmlElement
(
name =
"label"
,
type = OutLabel.
class
)})
private
List<OutLabel> labels =
new
ArrayList();
public
OutChild(){}
public
List<OutLabel> getLabels() {
return
labels;
}
public
void
setLabels(List<OutLabel> labels) {
this
.labels = labels;
}
public
void
setTypeName(String typeName) {
this
.typeName = typeName;
}
public
void
setTypeId(
int
typeId) {
this
.typeId = typeId;
}
public
String getTypeName() {
return
typeName;
}
public
int
getTypeId() {
return
typeId;
}
}
@XmlRootElement
@XmlAccessorType
(XmlAccessType.FIELD)
public
class
OutLabel
extends
ResponseBase {
@XmlAttribute
private
int
labelId;
@XmlAttribute
private
String labelName;
public
OutLabel(){}
public
int
getLabelId() {
return
labelId;
}
public
void
setLabelId(
int
labelId) {
this
.labelId = labelId;
}
public
String getLabelName() {
return
labelName;
}
public
void
setLabelName(String labelName) {
this
.labelName = labelName;
}
}
|
三、处理逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
@Override
public
LabelList labellist(Integer epgid) {
LabelList labelList =
new
LabelList();
if
(epgid ==
null
) {
labelList.setParamInvalidResponse(
"epgId"
, String.valueOf(epgid));
return
labelList;
}
int
treeid =
0
;
boolean
opl =
true
;
//geneTreeList-->labelList
GeneTreeList geneTreeList = treeService.getTreeList(epgid, treeid, opl);
if
(
null
== geneTreeList) {
labelList.setNoDataResponse();
return
labelList;
}
if
(geneTreeList.getTreeList().size() >
0
) {
ChangeIbsTreeList.change(labelList, geneTreeList);
labelList.setSucessResponse(ResponseStatus.Source.None);
}
else
{
labelList.setNoDataResponse();
}
return
labelList;
}
|
下面代码中注释的是我写的逻辑,很原始的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
public
class
ChangeIbsTreeList {
// private static boolean[] flag1 = new boolean[100];//以typeid为数组下标
public
static
void
change(LabelList labellist, GeneTreeList geneTreeList) {
List<GeneTreeLabel> geneTreeLabelList =
new
LinkedList<>();
//获取所有的label
for
(GeneTree geneTree : geneTreeList.getTreeList()) {
geneTreeLabelList.addAll(geneTree.getLabels());
}
if
(geneTreeLabelList.size() ==
0
) {
return
;
}
//根据lableid和typeid生成不同的map
//geneTreeLabelList.stream():可以用来获取流,参考:http://blog.csdn.net/u010425776/article/details/52344425 http://blog.csdn.net/u010425776/article/details/52346644
//根据List创建Map:Map<Integer, Integer> map = list.stream().collect(Collectors.toMap(p -> p, q->q*3));
//Collectors.toMap(GeneTreeLabel::getLabelId, c -> c, (e1, e2) -> e1):
// GeneTreeLabel::getLabelId:是接收一个任务并产生一个只包含该任务标题的键的Function
// c -> c:一个用来返回任务本身的lambda表达式:http://www.importnew.com/16436.html http://blog.csdn.net/u010425776/article/details/52334455
// (e1, e2) -> e1:处理重复问题
Map<Integer, GeneTreeLabel> lableMap = geneTreeLabelList.stream().collect(Collectors.toMap(GeneTreeLabel::getLabelId, c -> c, (e1, e2) -> e1));
Map<Integer, GeneTreeLabel> typeMap = geneTreeLabelList.stream().collect(Collectors.toMap(GeneTreeLabel::getTypeId, c -> c, (e1, e2) -> e1));
//按type分类
Map<Integer, List<GeneTreeLabel>> groupbyType =
geneTreeLabelList.stream().collect(groupingBy(GeneTreeLabel::getTypeId));
//遍历生成Childs
//t是integer类型
//map是映射:将GeneTreeLabel转换成GeneTreeLabel.getTypeId()为int类型,然后去重
//然后将int类型映射成函数需要的类型
//注:第三行用到了得到的lableMap、typeMap、groupbyType
List<OutChild> OutChilds =
(geneTreeLabelList.stream().map(GeneTreeLabel -> GeneTreeLabel.getTypeId()).distinct().collect(Collectors.toList()))
.stream().map(t -> GeneTreeLabel2OutChild(typeMap.get(t), groupbyType, lableMap)).collect(Collectors.toList());
//遍历Childs,set Labels
for
(OutChild child : OutChilds) {
child.setLabels((groupbyType.get(child.getTypeId()).stream().map(GeneTreeLabel::getLabelId).distinct().collect(Collectors.toList())).stream().map(t -> GeneTreeLabel2OutLabel(lableMap.get(t))).collect(Collectors.toList()));
}
labellist.setChilds(OutChilds);
// for (int i = 0; i < flag1.length; i++) {
// flag1[i] = false;
// }
// List<GeneTree> treeList = geneTreeList.getTreeList();
// List<OutChild> childList = new ArrayList<>();
// getTreeList(treeList, childList);
// labellist.setChilds(childList);
}
private
static
OutChild GeneTreeLabel2OutChild(GeneTreeLabel geneTreeLabel, Map<Integer, List<GeneTreeLabel>> groupbyType, Map<Integer, GeneTreeLabel> lableMap) {
OutChild outChild =
new
OutChild();
outChild.setTypeId(geneTreeLabel.getTypeId());
outChild.setTypeName(geneTreeLabel.getTypeName());
//List<OutLabel> labels = (groupbyType.get(geneTreeLabel.getTypeId()).stream().map(GeneTreeLabel -> GeneTreeLabel.getLabelId()).distinct().collect(Collectors.toList())).stream().map(t -> GeneTreeLabel2OutLabel(lableMap.get(t))).collect(Collectors.toList());
//OutChild.setLabels(null);
return
outChild;
}
private
static
OutLabel GeneTreeLabel2OutLabel(GeneTreeLabel geneTreeLabel) {
OutLabel outLabel =
new
OutLabel();
outLabel.setLabelId(geneTreeLabel.getLabelId());
outLabel.setLabelName(geneTreeLabel.getLabelName());
return
outLabel;
}
// public static void getTreeList(List<GeneTree> treeList, List<OutChild> childList) {
//
// Iterator<GeneTree> it = treeList.iterator();
// while (it.hasNext()) {
// GeneTree geneTree = it.next();
// List<GeneTreeLabel> labels = geneTree.getLabels();
// setLabels(labels, childList);
// }
// }
//
// public static void setLabels(List<GeneTreeLabel> labels, List<OutChild> childList) {
// Iterator<GeneTreeLabel> it = labels.iterator();
// while (it.hasNext()) {
// GeneTreeLabel label = it.next();
//
// if (false == flag1[label.getTypeId()]) {//如果标志为false,说明child不存在
// OutChild outChild = new OutChild();
// outChild.setTypeId(label.getTypeId());
// outChild.setTypeName(label.getTypeName());
//
// List<OutLabel> outLabellist = new ArrayList<>();
// OutLabel outLabel = new OutLabel();
// outLabel.setLabelId(label.getLabelId());
// outLabel.setLabelName(label.getLabelName());
// outLabellist.add(outLabel);
//
// outChild.setLabels(outLabellist);
//
// childList.add(outChild);
//
// flag1[label.getTypeId()] = true;
// } else { //否则已经建立这个类型的child,然后遍历child集合,找到对应的child
// Iterator<OutChild> it1 = childList.iterator();
// while (it1.hasNext()) {
// OutChild outChild = it1.next();
// if (outChild.getTypeId() == label.getTypeId()) {//找到对应的child,然后查找child里面的label是否重复
// List<OutLabel> outLabels = outChild.getLabels();
// Iterator<OutLabel> it2 = outLabels.iterator();
// int i = 0;
// while (it2.hasNext()) {//遍历得到label
// OutLabel outLabel = it2.next();
// if (outLabel.getLabelId() == label.getLabelId()) {
// break;
// }
// i = i + 1;
// }
// if (i >= outLabels.size()) {
// OutLabel outLabel = new OutLabel();
// outLabel.setLabelId(label.getLabelId());
// outLabel.setLabelName(label.getLabelName());
// outLabels.add(outLabel);
//
// outChild.setLabels(outLabels);
// }
// }
// }
// }
// }
// }
}
|