11package com .github .lokic .javaplus .join ;
22
3+ import com .github .lokic .javaplus .Functions ;
34import com .github .lokic .javaplus .NullData ;
45import com .github .lokic .javaplus .tuple .Tuple ;
56import com .github .lokic .javaplus .tuple .Tuple2 ;
1314
1415public 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}
0 commit comments