Skip to content

Commit

Permalink
com.feilong.core.util.CollectionsUtil 新建 Pair<List<O>, List<O>>
Browse files Browse the repository at this point in the history
splitDuplicate(Collection<O> objectCollection,String...propertyNames)
根据属性值,分隔新数据和重复的数据 fix #666
  • Loading branch information
venusdrogon committed Dec 13, 2023
1 parent b9c71a6 commit 66a269f
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 8 deletions.
2 changes: 1 addition & 1 deletion feilong-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ feilong core 让Java开发更简便的工具库
![JDK 1.8](https://img.shields.io/badge/JDK-1.8-green.svg "JDK 1.8")
[![jar size 110K](https://img.shields.io/badge/size-110K-green.svg "size 110K")](https://github.com/venusdrogon/feilong-platform/tree/repository/com/feilong/platform/feilong-core/1.14.0)
[![javadoc 83%](http://progressed.io/bar/83?title=javadoc "javadoc 83%")](http://venusdrogon.github.io/feilong-platform/javadocs/feilong-core/)
[![tests 2992](https://img.shields.io/badge/tests-2992%20%2F%202992-green.svg "tests 2992")](https://github.com/venusdrogon/feilong-core/tree/master/src/test/java/com/feilong/core)
[![tests 3001](https://img.shields.io/badge/tests-3001%20%2F%203001-green.svg "tests 3001")](https://github.com/venusdrogon/feilong-core/tree/master/src/test/java/com/feilong/core)
![Coverage 91%](http://progressed.io/bar/91?title=Coverage "Coverage 91%")

![sonar](http://venusdrogon.github.io/feilong-platform/mysource/sonar/feilong-core-summary2.jpg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import com.feilong.lib.collection4.CollectionUtils;
import com.feilong.lib.collection4.IterableUtils;
import com.feilong.lib.collection4.ListUtils;
import com.feilong.lib.lang3.tuple.Pair;

/**
* {@link Collection} 工具类,是 {@link Collections} 的扩展和补充.
Expand Down Expand Up @@ -766,6 +767,8 @@ public static <T> boolean addIgnoreNullOrEmpty(final Collection<T> objectCollect
return false;
}

//---------------------------------------------------------------

//默认没有改变
boolean result = false;
for (T element : elements){
Expand Down Expand Up @@ -1375,27 +1378,107 @@ public static <O> List<O> removeDuplicate(Collection<O> objectCollection,String.

//---------------------------------------------------------------
//用来识别是否重复
List<Map<String, Object>> mapList = newArrayList();
List<Map<String, Object>> allValueMapList = newArrayList();

//用来存放返回list
List<O> returnList = new ArrayList<>(size(objectCollection));

//---------------------------------------------------------------
for (O o : objectCollection){
Map<String, Object> propertyNameAndValueMap = PropertyUtil.describe(o, propertyNames);
boolean isNotExist = !isExist(mapList, propertyNameAndValueMap, propertyNames);
boolean isNotExist = !isExist(allValueMapList, propertyNameAndValueMap, propertyNames);
if (isNotExist){
returnList.add(o);
mapList.add(propertyNameAndValueMap);
allValueMapList.add(propertyNameAndValueMap);
}
}
return returnList;
}

/**
* 判断<code>mapList</code> 中,是否含有 指定 key-value 的map.
* 分隔集合,将新数据放left , 重复的数据放right.
*
* <p>
* 请自行先进行排序处理
* </p>
*
* <h3>示例:</h3>
*
* <blockquote>
*
* 有 User 对象,两个属性 id和age
*
* <pre class="code">
*
* User user1 = new User(1L, 15);
* User user2 = new User(1L, 16);
* User user3 = new User(1L, 15); //这条和第一条重复了
* List{@code <User>} list = toList(user1, user2, user3);
*
* Pair{@code <List<User>, List<User>>} splitDuplicate = CollectionsUtil.splitDuplicate(list, "id", "age");
*
* //left 保存的是不重复的数据
* List{@code <User>} newDuplicate = splitDuplicate.getLeft();
// right 保存的是和left有属性值重复的数据
* List{@code <User>} rightDuplicate = splitDuplicate.getRight();
*
* assertSame(2, newDuplicate.size());
* assertThat(newDuplicate, contains(user1, user2));
*
* assertSame(1, rightDuplicate.size());
* assertThat(rightDuplicate, contains(user3));
*
* </pre>
*
* </blockquote>
*
* @param <O>
* @param objectCollection
* the object collection
* @param propertyNames
* 包含的属性数组名字数组,(can be nested/indexed/mapped/combo),<br>
* 如果是null或者empty,那么直接调用 {@link #removeDuplicate(Collection)}<br>
* @return 将新数据放left , 重复的数据放right.<br>
* 如果 <code>propertyNames</code> 是null或者empty,返回 null<br>
* 如果 <code>objectCollection</code> 是null或者empty,返回 null<br>
* @since 4.0.7
*/
public static <O> Pair<List<O>, List<O>> splitDuplicate(Collection<O> objectCollection,String...propertyNames){
if (isNullOrEmpty(propertyNames)){
return null;
}
if (isNullOrEmpty(objectCollection)){
return null;
}

//---------------------------------------------------------------

//新数据
List<O> newList = new ArrayList<>(size(objectCollection));
//重复
List<O> duplicateList = new ArrayList<>(size(objectCollection));

//---------------------------------------------------------------

//用来识别是否重复
List<Map<String, Object>> allValueMapList = newArrayList();
for (O o : objectCollection){
Map<String, Object> propertyNameAndValueMap = PropertyUtil.describe(o, propertyNames);
boolean isNotExist = !isExist(allValueMapList, propertyNameAndValueMap, propertyNames);
if (isNotExist){
newList.add(o);
allValueMapList.add(propertyNameAndValueMap);
}else{
duplicateList.add(o);
}
}
return Pair.of(newList, duplicateList);
}

/**
* 判断<code>allValueMapList</code> 中,是否含有指定 key-value 的map.
*
* @param mapList
* @param allValueMapList
* the map list
* @param propertyNameAndValueMap
* the property name and value map
Expand All @@ -1404,8 +1487,8 @@ public static <O> List<O> removeDuplicate(Collection<O> objectCollection,String.
* @return 存在,返回true
* @since 2.1.0
*/
private static boolean isExist(List<Map<String, Object>> mapList,Map<String, Object> propertyNameAndValueMap,String...keys){
for (Map<String, Object> map : mapList){
private static boolean isExist(List<Map<String, Object>> allValueMapList,Map<String, Object> propertyNameAndValueMap,String...keys){
for (Map<String, Object> map : allValueMapList){
if (eqauls(map, propertyNameAndValueMap, keys)){
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
RemoveAllNullTest.class,
RemoveAllCollectionTest.class,

SplitDuplicatePropertyNamesTest.class,

ForEachTest.class,

SelectRegexStringPredicateTest.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Copyright (C) 2008 feilong
*
* 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.feilong.core.util.collectionsutil;

import static com.feilong.core.bean.ConvertUtil.toArray;
import static com.feilong.core.bean.ConvertUtil.toList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import com.feilong.core.util.CollectionsUtil;
import com.feilong.lib.lang3.tuple.Pair;
import com.feilong.store.member.User;
import com.feilong.store.member.UserInfo;

public class SplitDuplicatePropertyNamesTest{

@Test
public void testSplitDuplicate(){
User user1 = new User(1L, 15);
User user2 = new User(1L, 16);
User user3 = new User(1L, 15);
List<User> list = toList(user1, user2, user3);

Pair<List<User>, List<User>> splitDuplicate = CollectionsUtil.splitDuplicate(list, "id", "age");

List<User> newDuplicate = splitDuplicate.getLeft();
List<User> rightDuplicate = splitDuplicate.getRight();

assertSame(2, newDuplicate.size());
assertThat(newDuplicate, contains(user1, user2));

//---------------------------------------------------------------

assertSame(1, rightDuplicate.size());
assertThat(rightDuplicate, contains(user3));
}

@Test
public void testSplitDuplicate1(){
User user1 = new User(1L);
user1.setUserInfo(new UserInfo(15));

User user2 = new User(1L);
user2.setUserInfo(new UserInfo(16));

User user3 = new User(1L);
user3.setUserInfo(new UserInfo(15));

//---------------------------------------------------------------

List<User> list = toList(user1, user2, user3);

Pair<List<User>, List<User>> splitDuplicate = CollectionsUtil.splitDuplicate(list, "id", "userInfo.age");

List<User> newDuplicate = splitDuplicate.getLeft();
List<User> rightDuplicate = splitDuplicate.getRight();

assertSame(2, newDuplicate.size());
assertThat(newDuplicate, contains(user1, user2));

//---------------------------------------------------------------

assertSame(1, rightDuplicate.size());
assertThat(rightDuplicate, contains(user3));
}

//---------------------------------------------------------------

@Test
public void testSplitDuplicateNullCollection(){
assertEquals(null, CollectionsUtil.splitDuplicate(null, (String[]) null));
}

@Test
public void testSplitDuplicateNullCollection12(){
assertEquals(null, CollectionsUtil.splitDuplicate(null, toArray("")));
}

//---------------------------------------------------------------

@Test
public void testSplitDuplicateEmptyCollection(){
assertEquals(null, CollectionsUtil.splitDuplicate(new ArrayList<>(), (String[]) null));
}

@Test
public void testSplitDuplicateEmptyCollection333(){
assertEquals(null, CollectionsUtil.splitDuplicate(new ArrayList<>(), toArray("")));
}

//---------------------------------------------------------------

@Test
public void testSplitDuplicateEmptyCollection1(){
assertEquals(null, CollectionsUtil.splitDuplicate(toList(), (String[]) null));
}

@Test
public void testSplitDuplicateEmptyCollection1333(){
assertEquals(null, CollectionsUtil.splitDuplicate(toList(), toArray("")));
}
}

0 comments on commit 66a269f

Please sign in to comment.