com.landawn.abacus.util.Difference Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of abacus-android Show documentation
Show all versions of abacus-android Show documentation
A general and simple library for Android
/*
* Copyright (C) 2016 HaiYang Li
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.landawn.abacus.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
*
* @since 0.8
*
* @author Haiyang Li
*/
public class Difference {
final L common;
final L leftOnly;
final R rightOnly;
Difference(L common, L leftOnly, R rightOnly) {
this.common = common;
this.leftOnly = leftOnly;
this.rightOnly = rightOnly;
}
public static Difference, List> of(boolean[] a, boolean[] b) {
return of(BooleanList.of(a), BooleanList.of(b));
}
public static Difference, List> of(char[] a, char[] b) {
return of(CharList.of(a), CharList.of(b));
}
public static Difference, List> of(byte[] a, byte[] b) {
return of(ByteList.of(a), ByteList.of(b));
}
public static Difference, List> of(short[] a, short[] b) {
return of(ShortList.of(a), ShortList.of(b));
}
public static Difference, List> of(int[] a, int[] b) {
return of(IntList.of(a), IntList.of(b));
}
public static Difference, List> of(long[] a, long[] b) {
return of(LongList.of(a), LongList.of(b));
}
public static Difference, List> of(float[] a, float[] b) {
return of(FloatList.of(a), FloatList.of(b));
}
public static Difference, List> of(double[] a, double[] b) {
return of(DoubleList.of(a), DoubleList.of(b));
}
public static , R extends List> Difference of(T1[] a, T2[] b) {
return of(Arrays.asList(a), Arrays.asList(b));
}
/**
*
* @param a
* @param b
* @return
*/
public static , R extends List> Difference of(Collection extends T1> a, Collection extends T2> b) {
List common = new ArrayList<>();
List leftOnly = new ArrayList<>();
List rightOnly = new ArrayList<>();
if (N.isNullOrEmpty(a)) {
if (N.isNullOrEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly.addAll(b);
}
} else if (N.isNullOrEmpty(b)) {
leftOnly.addAll(a);
} else {
final Multiset bOccurrences = Multiset.from(b);
for (T1 e : a) {
if (bOccurrences.getAndRemove(e) > 0) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (T2 e : b) {
if (bOccurrences.getAndRemove(e) > 0) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>((L) common, (L) leftOnly, (R) rightOnly);
}
public static Difference, List> of(BooleanList a, BooleanList b) {
List common = new ArrayList<>();
List leftOnly = new ArrayList<>();
List rightOnly = new ArrayList<>();
if (N.isNullOrEmpty(a)) {
if (N.isNullOrEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.toList();
}
} else if (N.isNullOrEmpty(b)) {
leftOnly = a.toList();
} else {
final Multiset bOccurrences = b.toMultiset();
boolean e = false;
for (int i = 0, len = a.size(); i < len; i++) {
e = a.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
public static Difference, List> of(CharList a, CharList b) {
List common = new ArrayList<>();
List leftOnly = new ArrayList<>();
List rightOnly = new ArrayList<>();
if (N.isNullOrEmpty(a)) {
if (N.isNullOrEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.toList();
}
} else if (N.isNullOrEmpty(b)) {
leftOnly = a.toList();
} else {
final Multiset bOccurrences = b.toMultiset();
char e = 0;
for (int i = 0, len = a.size(); i < len; i++) {
e = a.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
public static Difference, List> of(ByteList a, ByteList b) {
List common = new ArrayList<>();
List leftOnly = new ArrayList<>();
List rightOnly = new ArrayList<>();
if (N.isNullOrEmpty(a)) {
if (N.isNullOrEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.toList();
}
} else if (N.isNullOrEmpty(b)) {
leftOnly = a.toList();
} else {
final Multiset bOccurrences = b.toMultiset();
byte e = 0;
for (int i = 0, len = a.size(); i < len; i++) {
e = a.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
public static Difference, List> of(ShortList a, ShortList b) {
List common = new ArrayList<>();
List leftOnly = new ArrayList<>();
List rightOnly = new ArrayList<>();
if (N.isNullOrEmpty(a)) {
if (N.isNullOrEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.toList();
}
} else if (N.isNullOrEmpty(b)) {
leftOnly = a.toList();
} else {
final Multiset bOccurrences = b.toMultiset();
short e = 0;
for (int i = 0, len = a.size(); i < len; i++) {
e = a.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
public static Difference, List> of(IntList a, IntList b) {
List common = new ArrayList<>();
List leftOnly = new ArrayList<>();
List rightOnly = new ArrayList<>();
if (N.isNullOrEmpty(a)) {
if (N.isNullOrEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.toList();
}
} else if (N.isNullOrEmpty(b)) {
leftOnly = a.toList();
} else {
final Multiset bOccurrences = b.toMultiset();
int e = 0;
for (int i = 0, len = a.size(); i < len; i++) {
e = a.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
public static Difference, List> of(LongList a, LongList b) {
List common = new ArrayList<>();
List leftOnly = new ArrayList<>();
List rightOnly = new ArrayList<>();
if (N.isNullOrEmpty(a)) {
if (N.isNullOrEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.toList();
}
} else if (N.isNullOrEmpty(b)) {
leftOnly = a.toList();
} else {
final Multiset bOccurrences = b.toMultiset();
long e = 0;
for (int i = 0, len = a.size(); i < len; i++) {
e = a.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
public static Difference, List> of(FloatList a, FloatList b) {
List common = new ArrayList<>();
List leftOnly = new ArrayList<>();
List rightOnly = new ArrayList<>();
if (N.isNullOrEmpty(a)) {
if (N.isNullOrEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.toList();
}
} else if (N.isNullOrEmpty(b)) {
leftOnly = a.toList();
} else {
final Multiset bOccurrences = b.toMultiset();
float e = 0;
for (int i = 0, len = a.size(); i < len; i++) {
e = a.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
public static Difference, List> of(DoubleList a, DoubleList b) {
List common = new ArrayList<>();
List leftOnly = new ArrayList<>();
List rightOnly = new ArrayList<>();
if (N.isNullOrEmpty(a)) {
if (N.isNullOrEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.toList();
}
} else if (N.isNullOrEmpty(b)) {
leftOnly = a.toList();
} else {
final Multiset bOccurrences = b.toMultiset();
double e = 0;
for (int i = 0, len = a.size(); i < len; i++) {
e = a.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.getAndRemove(e) > 0) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
public L inCommon() {
return common;
}
public L onLeftOnly() {
return leftOnly;
}
public R onRightOnly() {
return rightOnly;
}
@SuppressWarnings("rawtypes")
public boolean areEqual() {
return (leftOnly instanceof Map && (((Map) leftOnly).isEmpty() && ((Map) rightOnly).isEmpty()))
|| (leftOnly instanceof Collection && (((Collection) leftOnly).isEmpty() && ((Collection) rightOnly).isEmpty()));
}
@Override
public String toString() {
return "{inCommon=" + common + ", onLeftOnly=" + leftOnly + ", onRightOnly=" + rightOnly + "}";
}
public static final class MapDifference extends Difference {
private final D diffValues;
MapDifference(L common, L leftOnly, R rightOnly, D diff) {
super(common, leftOnly, rightOnly);
this.diffValues = diff;
}
/**
*
* @param map1
* @param map2
* @return
*/
public static , R extends Map, D extends Map, Pair>> MapDifference of(
final Map extends K1, ? extends V1> map1, final Map extends K2, ? extends V2> map2) {
final L common = (L) new LinkedHashMap<>();
final L leftOnly = (L) new LinkedHashMap<>();
final R rightOnly = (R) new LinkedHashMap<>();
final Map