将对列表转换为分组对列表
Convert List of pairs into list of grouped pairs
我找不到适合这个问题的线程名称:C
我有包含两个长值字段的对象列表:
class ObjectFromDb {
Long dbUserId;
Long apiUserId;
}
例如。它可能看起来像这样:
List<ObjectFromDb> dbList = {
{1, 1},
{2, 2},
{2, 3},
{3, 4},
{4, 4},
{5, 4},
{6, 5}
}
目标是将此列表分组到关系中。可能性是:
一对一,一对多,多对一。不允许多对多。
我的最终目标:
class FinalObject {
List<Long> dbIds;
List<Long> apiIds;
}
所以结果列表应该是:
List<FinalObject> finalList = {
{ {1} , {1} },
{ {2} , {2,3} },
{ {3,4,5}, {4} },
{ {6} , {5} }
}
这是我的问题。有没有算法可以解决这样的问题?或者如果有人知道如何处理它?我试图解决它,但它以十亿个 ifs 和 for 循环结束,所以我重新开始并以另一个十亿个循环结束..
这是解决方案的想法:
第一步(多对一关系):根据dbUserID
对dbList
进行排序,将apiUserIds
与相同的dbUserID
合并,去掉dbUserID
中的对应关系=11=](在代码中我建立了一个名为 updatedDbList1
的新列表)。
第2步(一对多关系):根据apiUserId
对dbList
进行排序,将dbUserIDs
与相同的apiUserIds
组合起来,去掉dbList
中的对应关系=11=](在代码中我建立了一个名为 updatedDbList2
的新列表)。
第 3 步(一对一关系):将剩余的关系添加到最终结果。
这是我想出来的,但我相信只要多加思考,它就能做得更干净。
List<FinalObject> finalList = new ArrayList<>();
//Step 1: Extract many to one relations
//assuming dbList is sorted according to dbUserId, if not perform dbList.sort() with custom comparator
List<ObjectFromDb> updatedDbList1 = new ArrayList<>();
ArrayList<Long> apiUserIDs = new ArrayList<Long>();
Long currentdbUserID = -1L;
for(int i=0; i < dbList.size(); i++) {
if(dbList.get(i).dbUserId != currentdbUserID) {
if(apiUserIDs.size() >= 2) {
ArrayList<Long> dbUserIDs = new ArrayList<Long>();
dbUserIDs.add(currentdbUserID);
finalList.add(new FinalObject(dbUserIDs, apiUserIDs));
}
if(i==dbList.size()-1 || dbList.get(i).dbUserId != dbList.get(i+1).dbUserId){
updatedDbList1.add(dbList.get(i));
}
currentdbUserID = dbList.get(i).dbUserId;
apiUserIDs = new ArrayList<Long>();
}
apiUserIDs.add(dbList.get(i).apiUserId);
}
//Step 2: Extract one to many relations
//assuming dbList is sorted according to apiUserId, if not perform dbList.sort() with custom comparator
List<ObjectFromDb> updatedDbList2 = new ArrayList<>();
ArrayList<Long> dbUserIDs = new ArrayList<Long>();
Long currentApiUserID = -1L;
for(int i=0; i < updatedDbList1.size(); i++) {
if(updatedDbList1.get(i).apiUserId != currentApiUserID) {
if(dbUserIDs.size() >= 2) {
apiUserIDs = new ArrayList<Long>();
apiUserIDs.add(currentApiUserID);
finalList.add(new FinalObject(dbUserIDs, apiUserIDs));
}
if(i==updatedDbList1.size()-1 || updatedDbList1.get(i).apiUserId != updatedDbList1.get(i+1).apiUserId){
updatedDbList2.add(updatedDbList1.get(i));
}
currentApiUserID = updatedDbList1.get(i).apiUserId;
dbUserIDs = new ArrayList<Long>();
}
dbUserIDs.add(updatedDbList1.get(i).dbUserId);
}
//Step 3: Extract one to one relations
for(int i=0; i < updatedDbList2.size(); i++) {
dbUserIDs = new ArrayList<Long>();
dbUserIDs.add(updatedDbList2.get(i).dbUserId);
apiUserIDs = new ArrayList<Long>();
apiUserIDs.add(updatedDbList2.get(i).apiUserId);
finalList.add(new FinalObject(dbUserIDs, apiUserIDs));
}
我不确定你的关系算法是否涵盖了所有可能性,但这里是提供你想要的输出的代码。
我解释了它的作用以及它如何处理评论。
// First it is gonna group dbUserIds and apiUserIds between each other. To keep this data, we are gonna use hashMaps
Map<Long, List<Long>> dbUserIdGroup = new HashMap<Long, List<Long>>();
Map<Long, List<Long>> apiUserIdGroup = new HashMap<Long, List<Long>>();
// To demonstrate the test data given by you
List<ObjectFromDb> dbList = new ArrayList<ObjectFromDb>();
dbList.add(new ObjectFromDb(1L, 1L));
dbList.add(new ObjectFromDb(2L, 2L));
dbList.add(new ObjectFromDb(2L, 3L));
dbList.add(new ObjectFromDb(3L, 4L));
dbList.add(new ObjectFromDb(4L, 4L));
dbList.add(new ObjectFromDb(5L, 4L));
dbList.add(new ObjectFromDb(6L, 5L));
// Iterating the given ObjectFromDb instances to group them
for (ObjectFromDb objectFromDb : dbList) {
// Grouping according to dbUserId
if (dbUserIdGroup.get(objectFromDb.getDbUserId()) == null) {
List<Long> group = new ArrayList<Long>();
group.add(objectFromDb.getApiUserId());
dbUserIdGroup.put(objectFromDb.getDbUserId(), group);
} else {
dbUserIdGroup.get(objectFromDb.getDbUserId()).add(objectFromDb.getApiUserId());
}
// Grouping according to apiUserId
if (apiUserIdGroup.get(objectFromDb.getApiUserId()) == null) {
List<Long> group = new ArrayList<Long>();
group.add(objectFromDb.getDbUserId());
apiUserIdGroup.put(objectFromDb.getApiUserId(), group);
} else {
apiUserIdGroup.get(objectFromDb.getApiUserId()).add(objectFromDb.getDbUserId());
}
}
// Up to now, we have two grouped hashmaps
// dbUserIdGroup -> {"1":[1],"2":[2,3],"3":[4],"4":[4],"5":[4],"6":[5]} // note that the key of this hashtable is dbUserId
// apiUserIdGroup -> {"1":[1],"2":[2],"3":[2],"4":[3,4,5],"5":[6]} // note that the key of this hashtable is apiUserId
Set<Long> dbUserIds = dbUserIdGroup.keySet(); // to iterate dbUserId group we get its keys (dbUserIds)
Set<List<Long>> existanceCheck = new HashSet<>(); // to avoid duplicated data
List<FinalObject> result = new ArrayList<FinalObject>(); // to keep the result
for (Long dbUserId : dbUserIds) {
FinalObject fObject = null;
List<Long> dbApiIdList = dbUserIdGroup.get(dbUserId);
if (dbApiIdList.size() == 1) { // if the value is the list with single element
List<Long> groupedDbUserId = apiUserIdGroup.get(dbApiIdList.get(0));
if (!existanceCheck.contains(groupedDbUserId)) {
fObject = new FinalObject(groupedDbUserId, dbApiIdList);
existanceCheck.add(groupedDbUserId);
result.add(fObject);
}
} else { // if the value is the list with multiple elements
List<Long> dbUserIdList = new ArrayList<Long>();
dbUserIdList.add(dbUserId);
fObject = new FinalObject(dbUserIdList, dbApiIdList);
result.add(fObject);
}
}
// Now you have a List<FinalObject> result array just like you want.
我找不到适合这个问题的线程名称:C 我有包含两个长值字段的对象列表:
class ObjectFromDb {
Long dbUserId;
Long apiUserId;
}
例如。它可能看起来像这样:
List<ObjectFromDb> dbList = {
{1, 1},
{2, 2},
{2, 3},
{3, 4},
{4, 4},
{5, 4},
{6, 5}
}
目标是将此列表分组到关系中。可能性是: 一对一,一对多,多对一。不允许多对多。
我的最终目标:
class FinalObject {
List<Long> dbIds;
List<Long> apiIds;
}
所以结果列表应该是:
List<FinalObject> finalList = {
{ {1} , {1} },
{ {2} , {2,3} },
{ {3,4,5}, {4} },
{ {6} , {5} }
}
这是我的问题。有没有算法可以解决这样的问题?或者如果有人知道如何处理它?我试图解决它,但它以十亿个 ifs 和 for 循环结束,所以我重新开始并以另一个十亿个循环结束..
这是解决方案的想法:
第一步(多对一关系):根据dbUserID
对dbList
进行排序,将apiUserIds
与相同的dbUserID
合并,去掉dbUserID
中的对应关系=11=](在代码中我建立了一个名为 updatedDbList1
的新列表)。
第2步(一对多关系):根据apiUserId
对dbList
进行排序,将dbUserIDs
与相同的apiUserIds
组合起来,去掉dbList
中的对应关系=11=](在代码中我建立了一个名为 updatedDbList2
的新列表)。
第 3 步(一对一关系):将剩余的关系添加到最终结果。
这是我想出来的,但我相信只要多加思考,它就能做得更干净。
List<FinalObject> finalList = new ArrayList<>();
//Step 1: Extract many to one relations
//assuming dbList is sorted according to dbUserId, if not perform dbList.sort() with custom comparator
List<ObjectFromDb> updatedDbList1 = new ArrayList<>();
ArrayList<Long> apiUserIDs = new ArrayList<Long>();
Long currentdbUserID = -1L;
for(int i=0; i < dbList.size(); i++) {
if(dbList.get(i).dbUserId != currentdbUserID) {
if(apiUserIDs.size() >= 2) {
ArrayList<Long> dbUserIDs = new ArrayList<Long>();
dbUserIDs.add(currentdbUserID);
finalList.add(new FinalObject(dbUserIDs, apiUserIDs));
}
if(i==dbList.size()-1 || dbList.get(i).dbUserId != dbList.get(i+1).dbUserId){
updatedDbList1.add(dbList.get(i));
}
currentdbUserID = dbList.get(i).dbUserId;
apiUserIDs = new ArrayList<Long>();
}
apiUserIDs.add(dbList.get(i).apiUserId);
}
//Step 2: Extract one to many relations
//assuming dbList is sorted according to apiUserId, if not perform dbList.sort() with custom comparator
List<ObjectFromDb> updatedDbList2 = new ArrayList<>();
ArrayList<Long> dbUserIDs = new ArrayList<Long>();
Long currentApiUserID = -1L;
for(int i=0; i < updatedDbList1.size(); i++) {
if(updatedDbList1.get(i).apiUserId != currentApiUserID) {
if(dbUserIDs.size() >= 2) {
apiUserIDs = new ArrayList<Long>();
apiUserIDs.add(currentApiUserID);
finalList.add(new FinalObject(dbUserIDs, apiUserIDs));
}
if(i==updatedDbList1.size()-1 || updatedDbList1.get(i).apiUserId != updatedDbList1.get(i+1).apiUserId){
updatedDbList2.add(updatedDbList1.get(i));
}
currentApiUserID = updatedDbList1.get(i).apiUserId;
dbUserIDs = new ArrayList<Long>();
}
dbUserIDs.add(updatedDbList1.get(i).dbUserId);
}
//Step 3: Extract one to one relations
for(int i=0; i < updatedDbList2.size(); i++) {
dbUserIDs = new ArrayList<Long>();
dbUserIDs.add(updatedDbList2.get(i).dbUserId);
apiUserIDs = new ArrayList<Long>();
apiUserIDs.add(updatedDbList2.get(i).apiUserId);
finalList.add(new FinalObject(dbUserIDs, apiUserIDs));
}
我不确定你的关系算法是否涵盖了所有可能性,但这里是提供你想要的输出的代码。
我解释了它的作用以及它如何处理评论。
// First it is gonna group dbUserIds and apiUserIds between each other. To keep this data, we are gonna use hashMaps
Map<Long, List<Long>> dbUserIdGroup = new HashMap<Long, List<Long>>();
Map<Long, List<Long>> apiUserIdGroup = new HashMap<Long, List<Long>>();
// To demonstrate the test data given by you
List<ObjectFromDb> dbList = new ArrayList<ObjectFromDb>();
dbList.add(new ObjectFromDb(1L, 1L));
dbList.add(new ObjectFromDb(2L, 2L));
dbList.add(new ObjectFromDb(2L, 3L));
dbList.add(new ObjectFromDb(3L, 4L));
dbList.add(new ObjectFromDb(4L, 4L));
dbList.add(new ObjectFromDb(5L, 4L));
dbList.add(new ObjectFromDb(6L, 5L));
// Iterating the given ObjectFromDb instances to group them
for (ObjectFromDb objectFromDb : dbList) {
// Grouping according to dbUserId
if (dbUserIdGroup.get(objectFromDb.getDbUserId()) == null) {
List<Long> group = new ArrayList<Long>();
group.add(objectFromDb.getApiUserId());
dbUserIdGroup.put(objectFromDb.getDbUserId(), group);
} else {
dbUserIdGroup.get(objectFromDb.getDbUserId()).add(objectFromDb.getApiUserId());
}
// Grouping according to apiUserId
if (apiUserIdGroup.get(objectFromDb.getApiUserId()) == null) {
List<Long> group = new ArrayList<Long>();
group.add(objectFromDb.getDbUserId());
apiUserIdGroup.put(objectFromDb.getApiUserId(), group);
} else {
apiUserIdGroup.get(objectFromDb.getApiUserId()).add(objectFromDb.getDbUserId());
}
}
// Up to now, we have two grouped hashmaps
// dbUserIdGroup -> {"1":[1],"2":[2,3],"3":[4],"4":[4],"5":[4],"6":[5]} // note that the key of this hashtable is dbUserId
// apiUserIdGroup -> {"1":[1],"2":[2],"3":[2],"4":[3,4,5],"5":[6]} // note that the key of this hashtable is apiUserId
Set<Long> dbUserIds = dbUserIdGroup.keySet(); // to iterate dbUserId group we get its keys (dbUserIds)
Set<List<Long>> existanceCheck = new HashSet<>(); // to avoid duplicated data
List<FinalObject> result = new ArrayList<FinalObject>(); // to keep the result
for (Long dbUserId : dbUserIds) {
FinalObject fObject = null;
List<Long> dbApiIdList = dbUserIdGroup.get(dbUserId);
if (dbApiIdList.size() == 1) { // if the value is the list with single element
List<Long> groupedDbUserId = apiUserIdGroup.get(dbApiIdList.get(0));
if (!existanceCheck.contains(groupedDbUserId)) {
fObject = new FinalObject(groupedDbUserId, dbApiIdList);
existanceCheck.add(groupedDbUserId);
result.add(fObject);
}
} else { // if the value is the list with multiple elements
List<Long> dbUserIdList = new ArrayList<Long>();
dbUserIdList.add(dbUserId);
fObject = new FinalObject(dbUserIdList, dbApiIdList);
result.add(fObject);
}
}
// Now you have a List<FinalObject> result array just like you want.