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-common Show documentation
Show all versions of abacus-common Show documentation
A general programming library in Java/Android. It's easy to learn and simple to use with concise and powerful APIs.
The newest version!
/*
* 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;
import java.util.function.BiPredicate;
import com.landawn.abacus.annotation.SuppressFBWarnings;
import com.landawn.abacus.util.function.TriPredicate;
/**
* It is used to compare two collections and find the common elements, elements only in the left collection, and elements only in the right collection. Occurrences are considered.
*
* @param
* @param
* @see N#difference(Collection, Collection)
* @see N#symmetricDifference(Collection, Collection)
* @see N#excludeAll(Collection, Collection)
* @see N#excludeAllToSet(Collection, Collection)
* @see N#removeAll(Collection, Iterable)
* @see N#intersection(Collection, Collection)
* @see N#commonSet(Collection, Collection)
*/
public class Difference {
final L common;
final L leftOnly;
final R rightOnly;
Difference(final L common, final L leftOnly, final R rightOnly) {
this.common = common;
this.leftOnly = leftOnly;
this.rightOnly = rightOnly;
}
/**
* Compares two boolean arrays and finds the common elements, elements only in the first array, and elements only in the second array.
*
* @param a The first boolean array to be compared.
* @param b The second boolean array to be compared.
* @return A Difference object containing the common elements, elements only in the first array, and elements only in the second array.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final boolean[] a, final boolean[] b) {
return of(BooleanList.of(a), BooleanList.of(b));
}
/**
* Compares two char arrays and finds the common elements, elements only in the first array, and elements only in the second array.
*
* @param a The first char array to be compared.
* @param b The second char array to be compared.
* @return A Difference object containing the common elements, elements only in the first array, and elements only in the second array.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final char[] a, final char[] b) {
return of(CharList.of(a), CharList.of(b));
}
/**
* Compares two byte arrays and finds the common elements, elements only in the first array, and elements only in the second array.
*
* @param a The first byte array to be compared.
* @param b The second byte array to be compared.
* @return A Difference object containing the common elements, elements only in the first array, and elements only in the second array.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final byte[] a, final byte[] b) {
return of(ByteList.of(a), ByteList.of(b));
}
/**
* Compares two short arrays and finds the common elements, elements only in the first array, and elements only in the second array.
*
* @param a The first short array to be compared.
* @param b The second short array to be compared.
* @return A Difference object containing the common elements, elements only in the first array, and elements only in the second array.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final short[] a, final short[] b) {
return of(ShortList.of(a), ShortList.of(b));
}
/**
* Compares two int arrays and finds the common elements, elements only in the first array, and elements only in the second array.
*
* @param a The first int array to be compared.
* @param b The second int array to be compared.
* @return A Difference object containing the common elements, elements only in the first array, and elements only in the second array.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final int[] a, final int[] b) {
return of(IntList.of(a), IntList.of(b));
}
/**
* Compares two long arrays and finds the common elements, elements only in the first array, and elements only in the second array.
*
* @param a The first long array to be compared.
* @param b The second long array to be compared.
* @return A Difference object containing the common elements, elements only in the first array, and elements only in the second array.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final long[] a, final long[] b) {
return of(LongList.of(a), LongList.of(b));
}
/**
* Compares two float arrays and finds the common elements, elements only in the first array, and elements only in the second array.
*
* @param a The first float array to be compared.
* @param b The second float array to be compared.
* @return A Difference object containing the common elements, elements only in the first array, and elements only in the second array.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final float[] a, final float[] b) {
return of(FloatList.of(a), FloatList.of(b));
}
/**
* Compares two double arrays and finds the common elements, elements only in the first array, and elements only in the second array.
*
* @param a The first double array to be compared.
* @param b The second double array to be compared.
* @return A Difference object containing the common elements, elements only in the first array, and elements only in the second array.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final double[] a, final double[] b) {
return of(DoubleList.of(a), DoubleList.of(b));
}
/**
* Compares two arrays and finds the common elements, elements only in the first array, and elements only in the second array.
*
* @param The type of elements in the first array.
* @param The type of elements in the second array.
* @param The type of List that contains elements of type T1.
* @param The type of List that contains elements of type T2.
* @param a The first array to be compared.
* @param b The second array to be compared.
* @return A Difference object containing the common elements, elements only in the first array, and elements only in the second array.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
* @see N#symmetricDifference(Collection, Collection)
* @see N#excludeAll(Collection, Collection)
* @see N#excludeAllToSet(Collection, Collection)
* @see N#removeAll(Collection, Iterable)
* @see N#intersection(Collection, Collection)
* @see N#commonSet(Collection, Collection)
*/
public static , R extends List> Difference of(final T1[] a, final T2[] b) {
return of(Arrays.asList(a), Arrays.asList(b));
}
/**
* Compares two collections and finds the common elements, elements only in the first collection, and elements only in the second collection.
*
* @param The type of elements in the first collection.
* @param The type of elements in the second collection.
* @param The type of List that contains elements of type T1.
* @param The type of List that contains elements of type T2.
* @param a The first collection to be compared.
* @param b The second collection to be compared.
* @return A Difference object containing the common elements, elements only in the first collection, and elements only in the second collection.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
* @see N#symmetricDifference(Collection, Collection)
* @see N#excludeAll(Collection, Collection)
* @see N#excludeAllToSet(Collection, Collection)
* @see N#removeAll(Collection, Iterable)
* @see N#intersection(Collection, Collection)
* @see N#commonSet(Collection, Collection)
*/
@SuppressWarnings("unlikely-arg-type")
public static , R extends List> Difference of(final Collection extends T1> a, final Collection extends T2> b) {
final List common = new ArrayList<>();
final List leftOnly = new ArrayList<>();
final List rightOnly = new ArrayList<>();
if (N.isEmpty(a)) {
if (N.isEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly.addAll(b);
}
} else if (N.isEmpty(b)) {
leftOnly.addAll(a);
} else {
final Multiset bOccurrences = Multiset.create(b);
for (final T1 e : a) {
//noinspection SuspiciousMethodCalls
if (bOccurrences.remove(e)) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (final T2 e : b) {
if (bOccurrences.remove(e)) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>((L) common, (L) leftOnly, (R) rightOnly);
}
/**
* Compares two BooleanLists and finds the common elements, elements only in the first list, and elements only in the second list.
*
* @param a The first BooleanList to be compared.
* @param b The second BooleanList to be compared.
* @return A Difference object containing the common elements, elements only in the first list, and elements only in the second list.
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final BooleanList a, final BooleanList b) {
final BooleanList common = new BooleanList();
BooleanList leftOnly = new BooleanList();
BooleanList rightOnly = new BooleanList();
if (N.isEmpty(a)) {
if (N.isEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.copy();
}
} else if (N.isEmpty(b)) {
leftOnly = a.copy();
} 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.remove(e)) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.remove(e)) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
/**
* Compares two CharLists and finds the common elements, elements only in the first list, and elements only in the second list.
*
* @param a The first CharList to be compared.
* @param b The second CharList to be compared.
* @return A Difference object containing the common elements, elements only in the first list, and elements only in the second list.
* @return
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final CharList a, final CharList b) {
final CharList common = new CharList();
CharList leftOnly = new CharList();
CharList rightOnly = new CharList();
if (N.isEmpty(a)) {
if (N.isEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.copy();
}
} else if (N.isEmpty(b)) {
leftOnly = a.copy();
} 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.remove(e)) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.remove(e)) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
/**
* Compares two ByteLists and finds the common elements, elements only in the first list, and elements only in the second list.
*
* @param a The first ByteList to be compared.
* @param b The second ByteList to be compared.
* @return
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final ByteList a, final ByteList b) {
final ByteList common = new ByteList();
ByteList leftOnly = new ByteList();
ByteList rightOnly = new ByteList();
if (N.isEmpty(a)) {
if (N.isEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.copy();
}
} else if (N.isEmpty(b)) {
leftOnly = a.copy();
} 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.remove(e)) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.remove(e)) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
/**
* Compares two ShortLists and finds the common elements, elements only in the first list, and elements only in the second list.
*
* @param a The first ShortList to be compared.
* @param b The second ShortList to be compared.
* @return
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final ShortList a, final ShortList b) {
final ShortList common = new ShortList();
ShortList leftOnly = new ShortList();
ShortList rightOnly = new ShortList();
if (N.isEmpty(a)) {
if (N.isEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.copy();
}
} else if (N.isEmpty(b)) {
leftOnly = a.copy();
} 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.remove(e)) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.remove(e)) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
/**
* Compares two IntLists and finds the common elements, elements only in the first list, and elements only in the second list.
*
* @param a The first IntList to be compared.
* @param b The second IntList to be compared.
* @return
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final IntList a, final IntList b) {
final IntList common = new IntList();
IntList leftOnly = new IntList();
IntList rightOnly = new IntList();
if (N.isEmpty(a)) {
if (N.isEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.copy();
}
} else if (N.isEmpty(b)) {
leftOnly = a.copy();
} 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.remove(e)) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.remove(e)) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
/**
* Compares two LongLists and finds the common elements, elements only in the first list, and elements only in the second list.
*
* @param a The first LongList to be compared.
* @param b The second LongList to be compared.
* @return
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final LongList a, final LongList b) {
final LongList common = new LongList();
LongList leftOnly = new LongList();
LongList rightOnly = new LongList();
if (N.isEmpty(a)) {
if (N.isEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.copy();
}
} else if (N.isEmpty(b)) {
leftOnly = a.copy();
} 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.remove(e)) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.remove(e)) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
/**
* Compares two FloatLists and finds the common elements, elements only in the first list, and elements only in the second list.
*
* @param a The first FloatList to be compared.
* @param b The second FloatList to be compared.
* @return
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final FloatList a, final FloatList b) {
final FloatList common = new FloatList();
FloatList leftOnly = new FloatList();
FloatList rightOnly = new FloatList();
if (N.isEmpty(a)) {
if (N.isEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.copy();
}
} else if (N.isEmpty(b)) {
leftOnly = a.copy();
} 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.remove(e)) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.remove(e)) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
/**
* Compares two DoubleLists and finds the common elements, elements only in the first list, and elements only in the second list.
*
* @param a The first DoubleList to be compared.
* @param b The second DoubleList to be compared.
* @return
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
*/
public static Difference of(final DoubleList a, final DoubleList b) {
final DoubleList common = new DoubleList();
DoubleList leftOnly = new DoubleList();
DoubleList rightOnly = new DoubleList();
if (N.isEmpty(a)) {
if (N.isEmpty(b)) {
// Do nothing. All empty.
} else {
rightOnly = b.copy();
}
} else if (N.isEmpty(b)) {
leftOnly = a.copy();
} 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.remove(e)) {
common.add(e);
} else {
leftOnly.add(e);
}
}
for (int i = 0, len = b.size(); i < len; i++) {
e = b.get(i);
if (bOccurrences.remove(e)) {
rightOnly.add(e);
}
if (bOccurrences.isEmpty()) {
break;
}
}
}
return new Difference<>(common, leftOnly, rightOnly);
}
/**
* Returns the common elements found in both collections.
*
* @return the common elements
*/
public L inCommon() {
return common;
}
/**
* Returns the elements that are only in the left collection.
*
* @return the elements only in the left collection
*/
public L onLeftOnly() {
return leftOnly;
}
/**
* Returns the elements that are only in the right collection.
*
* @return the elements only in the right collection
*/
public R onRightOnly() {
return rightOnly;
}
/**
* Checks if the two input collections have the exact same elements Occurrences matter.
*
* @return {@code true} if the two input collections have the exact same elements, {@code false} otherwise
*/
@SuppressWarnings("rawtypes")
public boolean areEqual() {
return (leftOnly instanceof Collection && (((Collection) leftOnly).isEmpty() && ((Collection) rightOnly).isEmpty()))
|| (leftOnly instanceof Map && (((Map) leftOnly).isEmpty() && ((Map) rightOnly).isEmpty()));
}
@Override
public String toString() {
return "{inCommon=" + common + ", onLeftOnly=" + leftOnly + ", onRightOnly=" + rightOnly + "}";
}
/**
* It is used to compare two maps and find the common elements, elements only in the left map, elements only in the right map, and elements with different values.
*
* @param
* @param
* @param
*
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
* @see N#symmetricDifference(Collection, Collection)
* @see N#excludeAll(Collection, Collection)
* @see N#excludeAllToSet(Collection, Collection)
* @see N#removeAll(Collection, Iterable)
* @see N#intersection(Collection, Collection)
* @see N#commonSet(Collection, Collection)
*/
public static final class MapDifference extends Difference {
/** The diff values. */
private final D diffValues;
/**
* Instantiates a new map difference.
*
* @param common
* @param leftOnly
* @param rightOnly
* @param withDifferentValues
*/
MapDifference(final L common, final L leftOnly, final R rightOnly, final D withDifferentValues) {
super(common, leftOnly, rightOnly);
diffValues = withDifferentValues;
}
/**
* Compares two maps and finds the common elements, elements only in the left map, elements only in the right map, and elements with different values.
*
* @param
* @param
* @param
* @param
* @param
* @param map1
* @param map2
* @return
* @see IntList#difference(IntList)
* @see N#difference(Collection, Collection)
* @see N#symmetricDifference(Collection, Collection)
* @see N#excludeAll(Collection, Collection)
* @see N#excludeAllToSet(Collection, Collection)
* @see N#removeAll(Collection, Iterable)
* @see N#intersection(Collection, Collection)
* @see N#commonSet(Collection, Collection)
*/
public static MapDifference
© 2015 - 2025 Weber Informatics LLC | Privacy Policy