Skip to content

Commit c626512

Browse files
authored
Merge pull request #4 from lokic/dev/0.2.0
feat: 支持left join的排序,不再兼容老的join方法
2 parents eaafb4b + 420b75e commit c626512

File tree

6 files changed

+100
-208
lines changed

6 files changed

+100
-208
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.lokic</groupId>
88
<artifactId>java-plus</artifactId>
9-
<version>0.1.4</version>
9+
<version>0.2.0</version>
1010
<name>java-plus</name>
1111
<description>Provide some useful extensions on the basis of java8 to make java more usable.</description>
1212
<url>https://github.com/lokic/java-plus</url>

src/main/java/com/github/lokic/javaplus/join/Join.java

-17
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,4 @@ public static <T> JoinStream<T> stream(Stream<T> stream) {
88
return new JoinStream<>(stream);
99
}
1010

11-
public static <T1, T2> JoinType<T1, T2> innerJoin(Stream<T1> left, Stream<T2> right) {
12-
return new JoinType<>(left, right, t -> t.getT1() != null && t.getT2() != null);
13-
}
14-
15-
public static <T1, T2> JoinType<T1, T2> leftOuterJoin(Stream<T1> left, Stream<T2> right) {
16-
return new JoinType<>(left, right, t -> t.getT1() != null);
17-
}
18-
19-
public static <T1, T2> JoinType<T1, T2> rightOuterJoin(Stream<T1> left, Stream<T2> right) {
20-
return new JoinType<>(left, right, t -> t.getT2() != null);
21-
}
22-
23-
public static <T1, T2> JoinType<T1, T2> fullOuterJoin(Stream<T1> left, Stream<T2> right) {
24-
return new JoinType<>(left, right, t -> !(t.getT1() == null && t.getT2() == null));
25-
}
26-
27-
2811
}

src/main/java/com/github/lokic/javaplus/join/JoinStream.java

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.github.lokic.javaplus.join;
22

3+
import com.github.lokic.javaplus.tuple.Tuple;
4+
35
import java.util.function.Function;
46
import java.util.stream.Stream;
57

@@ -18,22 +20,6 @@ public <R> Stream<R> flattenStream(Function<? super T, ? extends R> mapper) {
1820
return left.map(mapper);
1921
}
2022

21-
public <T3> JoinType<T, T3> innerJoin(Stream<T3> right) {
22-
return Join.innerJoin(left, right);
23-
}
24-
25-
public <T3> JoinType<T, T3> leftOuterJoin(Stream<T3> right) {
26-
return Join.leftOuterJoin(left, right);
27-
}
28-
29-
public <T3> JoinType<T, T3> rightOuterJoin(Stream<T3> right) {
30-
return Join.rightOuterJoin(left, right);
31-
}
32-
33-
public <T3> JoinType<T, T3> fullOuterJoin(Stream<T3> right) {
34-
return Join.fullOuterJoin(left, right);
35-
}
36-
3723
public <U, K, R> JoinStream<R> innerJoin(Stream<U> right, JoinOn<T, U, K, R> on) {
3824
Stream<R> stream = innerJoin(right)
3925
.on(on.getLeftKey(), on.getRightKey())
@@ -50,9 +36,10 @@ public <U, K, R> JoinStream<R> leftOuterJoin(Stream<U> right, JoinOn<T, U, K, R>
5036

5137

5238
public <U, K, R> JoinStream<R> rightOuterJoin(Stream<U> right, JoinOn<T, U, K, R> on) {
53-
Stream<R> stream = rightOuterJoin(right)
54-
.on(on.getLeftKey(), on.getRightKey())
55-
.flattenStream(on.getFlatten());
39+
Stream<R> stream = new JoinStream<>(right)
40+
.leftOuterJoin(left)
41+
.on(on.getRightKey(), on.getLeftKey())
42+
.flattenStream(t -> on.getFlatten().apply(Tuple.of(t.getT2(), t.getT1())));
5643
return new JoinStream<>(stream);
5744
}
5845

@@ -63,4 +50,17 @@ public <U, K, R> JoinStream<R> fullOuterJoin(Stream<U> right, JoinOn<T, U, K, R>
6350
.flattenStream(on.getFlatten());
6451
return new JoinStream<>(stream);
6552
}
53+
54+
private <U> JoinType<T, U> innerJoin(Stream<U> right) {
55+
return new JoinType<>(left, right, t -> t.getT1() != null && t.getT2() != null);
56+
}
57+
58+
private <U> JoinType<T, U> leftOuterJoin(Stream<U> right) {
59+
return new JoinType<>(left, right, t -> t.getT1() != null);
60+
}
61+
62+
private <U> JoinType<T, U> fullOuterJoin(Stream<U> right) {
63+
return new JoinType<>(left, right, t -> !(t.getT1() == null && t.getT2() == null));
64+
}
65+
6666
}

src/main/java/com/github/lokic/javaplus/join/JoinType.java

+46-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.github.lokic.javaplus.join;
22

3+
import com.github.lokic.javaplus.Functions;
34
import com.github.lokic.javaplus.NullData;
45
import com.github.lokic.javaplus.tuple.Tuple;
56
import com.github.lokic.javaplus.tuple.Tuple2;
@@ -13,23 +14,23 @@
1314

1415
public class JoinType<T1, T2> {
1516

16-
private final Stream<Tuple2<T1, T2>> leftWrappedStream;
17-
private final Stream<Tuple2<T1, T2>> rightWrappedStream;
17+
private final Stream<Tuple2<Integer, Tuple2<T1, T2>>> leftWrappedStream;
18+
private final Stream<Tuple2<Integer, Tuple2<T1, T2>>> rightWrappedStream;
1819
private final Predicate<Tuple2<T1, T2>> joinMatcher;
1920

2021
JoinType(Stream<T1> left, Stream<T2> right, Predicate<Tuple2<T1, T2>> joinMatcher) {
21-
this.leftWrappedStream = left.map(l -> Tuple.of(Objects.requireNonNull(l), null));
22-
this.rightWrappedStream = right.map(r -> Tuple.of(null, Objects.requireNonNull(r)));
22+
this.leftWrappedStream = left.map(l -> Tuple.of(Objects.requireNonNull(l), (T2) null)).map(Functions.mapWithIndex(Tuple::of));
23+
this.rightWrappedStream = right.map(r -> Tuple.of((T1) null, Objects.requireNonNull(r))).map(Functions.mapWithIndex(Tuple::of));
2324
this.joinMatcher = joinMatcher;
2425
}
2526

2627
public <K> JoinStream<Tuple2<T1, T2>> on(Function<T1, K> leftKey, Function<T2, K> rightKey) {
2728
Stream<Tuple2<T1, T2>> stream = Stream.concat(leftWrappedStream, rightWrappedStream)
2829
.collect(Collectors.toMap(
29-
t -> matchKey(t, leftKey, rightKey),
30+
t -> matchKey(t.getT2(), leftKey, rightKey),
3031
Collections::singletonList,
3132
(a, b) -> {
32-
List<Tuple2<T1, T2>> li = new ArrayList<>();
33+
List<Tuple2<Integer, Tuple2<T1, T2>>> li = new ArrayList<>();
3334
li.addAll(a);
3435
li.addAll(b);
3536
return li;
@@ -39,7 +40,9 @@ public <K> JoinStream<Tuple2<T1, T2>> on(Function<T1, K> leftKey, Function<T2, K
3940
.values()
4041
.stream()
4142
.flatMap(this::cartesian)
42-
.filter(this.joinMatcher);
43+
.sorted(this::compare)
44+
.filter(t -> joinMatcher.test(t.getT2()))
45+
.map(Tuple2::getT2);
4346
return new JoinStream<>(stream);
4447
}
4548

@@ -49,18 +52,21 @@ public <K> JoinStream<Tuple2<T1, T2>> on(Function<T1, K> leftKey, Function<T2, K
4952
* @param li
5053
* @return
5154
*/
52-
private Stream<Tuple2<T1, T2>> cartesian(List<Tuple2<T1, T2>> li) {
53-
Map<Boolean, List<Tuple2<T1, T2>>> map = li.stream()
54-
.collect(Collectors.partitioningBy(this::isLeft, this.toListOrNullList()));
55-
List<Tuple2<T1, T2>> left = map.get(true);
56-
List<Tuple2<T1, T2>> right = map.get(false);
55+
private Stream<Tuple2<Tuple2<Integer, Integer>, Tuple2<T1, T2>>> cartesian(List<Tuple2<Integer, Tuple2<T1, T2>>> li) {
56+
Map<Boolean, List<Tuple2<Integer, Tuple2<T1, T2>>>> map = li.stream()
57+
.collect(Collectors.partitioningBy(t -> isLeft(t.getT2()), this.toListOrNullList()));
58+
List<Tuple2<Integer, Tuple2<T1, T2>>> left = map.get(true);
59+
List<Tuple2<Integer, Tuple2<T1, T2>>> right = map.get(false);
5760
return left.stream()
5861
.flatMap(l -> right.stream()
5962
.map(r -> this.merge(l, r)));
6063
}
6164

62-
private Tuple2<T1, T2> merge(Tuple2<T1, T2> l, Tuple2<T1, T2> r) {
63-
return Tuple.of(l == null ? null : l.getT1(), r == null ? null : r.getT2());
65+
66+
private Tuple2<Tuple2<Integer, Integer>, Tuple2<T1, T2>> merge(Tuple2<Integer, Tuple2<T1, T2>> l, Tuple2<Integer, Tuple2<T1, T2>> r) {
67+
return Tuple.of(
68+
Tuple.of(l == null ? null : l.getT1(), r == null ? null : r.getT1()),
69+
Tuple.of(l == null ? null : l.getT2().getT1(), r == null ? null : r.getT2().getT2()));
6470
}
6571

6672
private boolean isLeft(Tuple2<T1, T2> t) {
@@ -93,4 +99,30 @@ private <T> Collector<T, List<T>, List<T>> toListOrNullList() {
9399
}
94100
);
95101
}
102+
103+
private int compare(Tuple2<Tuple2<Integer, Integer>, Tuple2<T1, T2>> a, Tuple2<Tuple2<Integer, Integer>, Tuple2<T1, T2>> b) {
104+
Tuple2<Integer, Integer> ta = a.getT1();
105+
Tuple2<Integer, Integer> tb = b.getT1();
106+
107+
int cmp = compare(ta.getT1(), tb.getT1());
108+
if (cmp == 0) {
109+
return compare(ta.getT2(), tb.getT2());
110+
}
111+
return cmp;
112+
}
113+
114+
115+
private int compare(Integer a, Integer b) {
116+
if (a == null && b == null) {
117+
return 0;
118+
}
119+
if (a == null) {
120+
return 1;
121+
}
122+
if (b == null) {
123+
return -1;
124+
}
125+
return Integer.compare(a, b);
126+
}
127+
96128
}

src/test/java/com/github/lokic/javaplus/join/Join2Test.java

-128
This file was deleted.

0 commit comments

Comments
 (0)