mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
fix code
This commit is contained in:
parent
d17eb88635
commit
b5dc741079
@ -364,28 +364,13 @@ public class CollUtil {
|
||||
* 结果:[a, b, c],此结果中只保留了一个c
|
||||
*
|
||||
* @param <T> 集合元素类型
|
||||
* @param coll1 集合1
|
||||
* @param coll2 集合2
|
||||
* @param otherColls 其它集合
|
||||
* @param colls 集合列表
|
||||
* @return 交集的集合,返回 {@link LinkedHashSet}
|
||||
* @since 5.3.9
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <T> Set<T> intersectionDistinct(final Collection<T> coll1, final Collection<T> coll2, final Collection<T>... otherColls) {
|
||||
// 任意容器为空, 则返回空集
|
||||
if (isEmpty(coll1) || isEmpty(coll2) || ArrayUtil.hasEmpty((Object[]) otherColls)) {
|
||||
return new LinkedHashSet<>();
|
||||
}
|
||||
final Set<T> result = new LinkedHashSet<>(coll1);
|
||||
result.retainAll(coll2);
|
||||
|
||||
if (ArrayUtil.isNotEmpty(otherColls)) {
|
||||
for (final Collection<T> otherColl : otherColls) {
|
||||
result.retainAll(otherColl);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
public static <T> Set<T> intersectionDistinct(final Collection<T>... colls) {
|
||||
return CollectionOperation.of(colls).intersectionDistinct();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -407,30 +392,7 @@ public class CollUtil {
|
||||
* @return 差集的集合,返回 {@link ArrayList}
|
||||
*/
|
||||
public static <T> Collection<T> disjunction(final Collection<T> coll1, final Collection<T> coll2) {
|
||||
if (isEmpty(coll1) || isEmpty(coll2)) {
|
||||
if (isEmpty(coll1) && isEmpty(coll2)) {
|
||||
return ListUtil.zero();
|
||||
} else if (isEmpty(coll1)) {
|
||||
return coll2;
|
||||
} else if (isEmpty(coll2)) {
|
||||
return coll1;
|
||||
}
|
||||
}
|
||||
|
||||
final List<T> result = new ArrayList<>();
|
||||
final Map<T, Integer> map1 = countMap(coll1);
|
||||
final Map<T, Integer> map2 = countMap(coll2);
|
||||
// 两个集合的全部元素
|
||||
final Set<T> elements = SetUtil.of(map1.keySet());
|
||||
elements.addAll(map2.keySet());
|
||||
// 元素的个数为 该元素在两个集合中的个数的差
|
||||
for (final T t : elements) {
|
||||
final int amount = Math.abs(map1.getOrDefault(t, 0) - map2.getOrDefault(t, 0));
|
||||
for (int i = 0; i < amount; i++) {
|
||||
result.add(t);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return CollectionOperation.of(coll1, coll2).disjunction();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -469,23 +431,7 @@ public class CollUtil {
|
||||
* @since 5.3.5
|
||||
*/
|
||||
public static <T> List<T> subtractToList(final Collection<T> coll1, final Collection<T> coll2) {
|
||||
|
||||
if (isEmpty(coll1)) {
|
||||
return ListUtil.empty();
|
||||
}
|
||||
if (isEmpty(coll2)) {
|
||||
return ListUtil.of(true, coll1);
|
||||
}
|
||||
|
||||
//将被交数用链表储存,防止因为频繁扩容影响性能
|
||||
final List<T> result = new LinkedList<>();
|
||||
final Set<T> set = new HashSet<>(coll2);
|
||||
for (final T t : coll1) {
|
||||
if (false == set.contains(t)) {
|
||||
result.add(t);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return CollectionOperation.of(coll1, coll2).subtract();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -588,39 +534,10 @@ public class CollUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 针对Set的优化
|
||||
if (coll1 instanceof Set) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
return coll1.containsAll(coll2);
|
||||
}
|
||||
|
||||
final Iterator<?> iterator = coll1.iterator();
|
||||
// 保存 集合1 已经遍历过的元素
|
||||
final Set<Object> elementsAlreadySeen = new HashSet<>();
|
||||
for (final Object curElement : coll2) {
|
||||
// 集合2的当前元素 已经在集合1中
|
||||
if (elementsAlreadySeen.contains(curElement)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 集合2的当前元素 是否在集合1中
|
||||
boolean foundCurrentElement = false;
|
||||
while (iterator.hasNext()) {
|
||||
final Object next = iterator.next();
|
||||
elementsAlreadySeen.add(next);
|
||||
if (Objects.equals(curElement, next)) {
|
||||
foundCurrentElement = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 集合2的当前元素 不在集合1中, 显然不是子集
|
||||
if (!foundCurrentElement) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据集合返回一个元素计数的 {@link Map}<br>
|
||||
* 所谓元素计数就是假如这个集合中某个元素出现了n次,那将这个元素做为key,n做为value<br>
|
||||
@ -1771,11 +1688,14 @@ public class CollUtil {
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static <T> T get(final Collection<T> collection, int index) {
|
||||
if (isEmpty(collection)) {
|
||||
if (null == collection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int size = collection.size();
|
||||
if (0 == size) {
|
||||
return null;
|
||||
}
|
||||
if (index < 0) {
|
||||
index += size;
|
||||
}
|
||||
@ -2193,10 +2113,10 @@ public class CollUtil {
|
||||
if (isEmpty(mapCollection)) {
|
||||
return ListUtil.zero();
|
||||
}
|
||||
// 统计每个map的values的大小总和
|
||||
// 统计每个map的大小总和
|
||||
int size = 0;
|
||||
for (final Map<?, V> map : mapCollection) {
|
||||
size += size(map.values());
|
||||
size += map.size();
|
||||
}
|
||||
if (size == 0) {
|
||||
return ListUtil.zero();
|
||||
@ -2448,41 +2368,6 @@ public class CollUtil {
|
||||
return IterUtil.isEqualList(list1, list2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断两个集合是否包含相同的元素(包括个数)
|
||||
*
|
||||
* @param coll1 集合1
|
||||
* @param coll2 集合2
|
||||
* @return 两个集合是否相同
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static boolean isEquals(final Collection<?> coll1, final Collection<?> coll2) {
|
||||
if (coll1 == coll2) {
|
||||
return true;
|
||||
}
|
||||
if (coll1 == null || coll2 == null || coll1.size() != coll2.size()) {
|
||||
return false;
|
||||
}
|
||||
// 针对 Set 的优化
|
||||
if (coll1 instanceof Set || coll2 instanceof Set) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
return coll1 instanceof Set ? coll1.containsAll(coll2) : coll2.containsAll(coll1);
|
||||
}
|
||||
|
||||
// 给集合1的每个元素计数
|
||||
//noinspection unchecked
|
||||
final Map<Object, Integer> countMap1 = countMap((Iterable<Object>) coll1);
|
||||
|
||||
for (final Object e : coll2) {
|
||||
// 该元素若存在, 则个数减去1, 若不存在则个数为-1
|
||||
final Integer amount = countMap1.merge(e, -1, Integer::sum);
|
||||
if (amount < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 一个对象不为空且不存在于该集合中时,加入到该集合中<br>
|
||||
* <pre>
|
||||
|
@ -11,7 +11,14 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 集合运算
|
||||
* 集合运算,包括:
|
||||
* <ul>
|
||||
* <li>求集合的并集</li>
|
||||
* <li>求集合的唯一并集</li>
|
||||
* <li>求集合的完全并集</li>
|
||||
* <li>求集合的交集</li>
|
||||
* <li>求集合的差集</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param <E> 集合元素类型
|
||||
*/
|
||||
@ -137,6 +144,82 @@ public class CollectionOperation<E> {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多个集合的唯一交集<br>
|
||||
* 针对一个集合中存在多个相同元素的情况,只保留一个<br>
|
||||
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]<br>
|
||||
* 结果:[a, b, c],此结果中只保留了一个c
|
||||
*
|
||||
* @return 唯一交集的集合,返回 {@link LinkedHashSet}
|
||||
*/
|
||||
public Set<E> intersectionDistinct() {
|
||||
final Collection<E>[] colls = this.colls;
|
||||
// 任意容器为空, 则返回空集
|
||||
if (ArrayUtil.isEmpty(colls)) {
|
||||
return SetUtil.zeroLinked();
|
||||
}
|
||||
|
||||
final Set<E> result = SetUtil.of(true, colls[0]);
|
||||
for (int i = 1; i < colls.length; i++) {
|
||||
if(CollUtil.isNotEmpty(colls[i])){
|
||||
result.retainAll(colls[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多个集合的差集<br>
|
||||
* 针对一个集合中存在多个相同元素的情况,计算每两个集合中此元素的个数,保留两个集合中此元素个数差的个数<br>
|
||||
* 例如:
|
||||
*
|
||||
* <pre>
|
||||
* disjunction([a, b, c, c, c], [a, b, c, c]) -》 [c]
|
||||
* disjunction([a, b], []) -》 [a, b]
|
||||
* disjunction([a, b, c], [b, c, d]) -》 [a, d]
|
||||
* </pre>
|
||||
* 任意一个集合为空,返回另一个集合<br>
|
||||
* 两个集合无差集则返回空集合
|
||||
*
|
||||
* @return 差集的集合,返回 {@link ArrayList}
|
||||
*/
|
||||
public Collection<E> disjunction() {
|
||||
final Collection<E>[] colls = this.colls;
|
||||
if (ArrayUtil.isEmpty(colls)) {
|
||||
return ListUtil.zero();
|
||||
}
|
||||
|
||||
Collection<E> result = colls[0];
|
||||
for (int i = 1; i < colls.length; i++) {
|
||||
result = _disjunction(result, colls[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算集合的单差集,即只返回【集合1】中有,但是【集合2】、【集合3】...中没有的元素,例如:
|
||||
*
|
||||
* <pre>
|
||||
* subtract([1,2,3,4],[2,3,4,5]) -》 [1]
|
||||
* </pre>
|
||||
*
|
||||
* @return 单差集的List
|
||||
*/
|
||||
public List<E> subtract() {
|
||||
final Collection<E>[] colls = this.colls;
|
||||
if(ArrayUtil.isEmpty(colls)){
|
||||
return ListUtil.zero();
|
||||
}
|
||||
final List<E> result = ListUtil.of(colls[0]);
|
||||
for (int i = 1; i < colls.length; i++) {
|
||||
result.removeAll(colls[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// region private methods
|
||||
/**
|
||||
* 两个集合的并集<br>
|
||||
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留最多的个数<br>
|
||||
@ -206,4 +289,49 @@ public class CollectionOperation<E> {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 两个集合的差集<br>
|
||||
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留两个集合中此元素个数差的个数<br>
|
||||
* 例如:
|
||||
*
|
||||
* <pre>
|
||||
* disjunction([a, b, c, c, c], [a, b, c, c]) -》 [c]
|
||||
* disjunction([a, b], []) -》 [a, b]
|
||||
* disjunction([a, b, c], [b, c, d]) -》 [a, d]
|
||||
* </pre>
|
||||
* 任意一个集合为空,返回另一个集合<br>
|
||||
* 两个集合无差集则返回空集合
|
||||
*
|
||||
* @param <T> 集合元素类型
|
||||
* @param coll1 集合1
|
||||
* @param coll2 集合2
|
||||
* @return 差集的集合,返回 {@link ArrayList}
|
||||
*/
|
||||
private static <T> Collection<T> _disjunction(final Collection<T> coll1, final Collection<T> coll2) {
|
||||
if(CollUtil.isEmpty(coll1)){
|
||||
if(CollUtil.isEmpty(coll2)){
|
||||
return ListUtil.zero();
|
||||
}
|
||||
return coll2;
|
||||
} else if(CollUtil.isEmpty(coll2)){
|
||||
return coll1;
|
||||
}
|
||||
|
||||
final List<T> result = new ArrayList<>(coll1.size() + coll2.size());
|
||||
final Map<T, Integer> map1 = CollUtil.countMap(coll1);
|
||||
final Map<T, Integer> map2 = CollUtil.countMap(coll2);
|
||||
// 两个集合的全部元素
|
||||
final Set<T> elements = SetUtil.of(map1.keySet());
|
||||
elements.addAll(map2.keySet());
|
||||
// 元素的个数为 该元素在两个集合中的个数的差
|
||||
for (final T t : elements) {
|
||||
final int amount = Math.abs(map1.getOrDefault(t, 0) - map2.getOrDefault(t, 0));
|
||||
for (int i = 0; i < amount; i++) {
|
||||
result.add(t);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
@ -186,6 +186,17 @@ public class SetUtil {
|
||||
return new HashSet<>(0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个初始大小为0的LinkedHashSet,这个空Set可变
|
||||
*
|
||||
* @param <T> 元素类型
|
||||
* @return 空的List
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static <T> Set<T> zeroLinked() {
|
||||
return new LinkedHashSet<>(0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转为只读Set
|
||||
*
|
||||
|
@ -1121,19 +1121,4 @@ public class CollUtilTest {
|
||||
Assert.assertFalse(CollUtil.isEqualList(list, ListUtil.of(1, 2, 3)));
|
||||
Assert.assertFalse(CollUtil.isEqualList(list, ListUtil.of(4, 3, 2, 1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEqualsTest() {
|
||||
final List<Integer> list = ListUtil.of(1, 2, 3, 4);
|
||||
Assert.assertTrue(CollUtil.isEquals(null, null));
|
||||
Assert.assertTrue(CollUtil.isEquals(ListUtil.of(), ListUtil.of()));
|
||||
Assert.assertTrue(CollUtil.isEquals(list, list));
|
||||
Assert.assertTrue(CollUtil.isEquals(list, ListUtil.of(1, 2, 3, 4)));
|
||||
Assert.assertTrue(CollUtil.isEquals(list, ListUtil.of(4, 3, 2, 1)));
|
||||
Assert.assertTrue(CollUtil.isEquals(list, SetUtil.of(4, 3, 2, 1)));
|
||||
|
||||
Assert.assertFalse(CollUtil.isEquals(null, ListUtil.of()));
|
||||
Assert.assertFalse(CollUtil.isEquals(list, ListUtil.of(1, 2, 3, 3)));
|
||||
Assert.assertFalse(CollUtil.isEquals(list, ListUtil.of(1, 2, 3)));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user