Java 组合几乎相等的数据列表的值
所以我以前问过,但我似乎不太清楚我在说什么,所以我现在想说得更清楚: 我要做的是为导入准备数据。我得到的数据是人为的,效率不高,所以我删除了不必要的条目,并尽可能多地合并数据 它的功能类似于配置程序。我得到的数据如下所示: 123:45:AB=12 这意味着:如果选项1是1或2或3,选项2是4或5,选项3是A或B,结果将是1和2 我创建了一个类似这样的类:Java 组合几乎相等的数据列表的值,java,list,merge,java-stream,Java,List,Merge,Java Stream,所以我以前问过,但我似乎不太清楚我在说什么,所以我现在想说得更清楚: 我要做的是为导入准备数据。我得到的数据是人为的,效率不高,所以我删除了不必要的条目,并尽可能多地合并数据 它的功能类似于配置程序。我得到的数据如下所示: 123:45:AB=12 这意味着:如果选项1是1或2或3,选项2是4或5,选项3是A或B,结果将是1和2 我创建了一个类似这样的类: Class Options{ String opt1; String opt2; String opt3;
Class Options{
String opt1;
String opt2;
String opt3;
String optResult;
//and some other stuff
boolean hasSameOptions(Options o){
return opt1.equals(o.opt1) && opt2.equals(o.opt2) && opt3.equals(o.opt3);
}
public void AddOptions(String options) {
for (String s : options.split("")) {
if (!optResult.contains(s)) {
optResult = optResult + s;
}
}
}
}
public static List<Options> cleanList(List<Options> oldList) {
List<Options> newList = new ArrayList<>();
for (Options item : oldList) {
Options temp = findEqualOptions(newList, item);
if (temp != null)
temp.AddOptions(item.optResult);
else
newList.add(item);
}
return newList;
}
public static <T> T findByProperty(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(Objects::nonNull).filter(filter).findFirst().orElse(null);
}
public static Options findEqualOptions(List<Options> list, Options opt) {
return findByProperty(list, d -> d.hasSameOptions(opt));
}
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
Option o1 = list.get(i);
Option o2 = list.get(j);
int diff1 = 0;
int diff2 = 0;
int diff3 = 0;
int diff4 = 0;
if(!o1.opt1.equals(o2.opt1))
diff1 = 1;
if(!o1.opt2.equals(o2.opt2))
diff2 = 1;
//and so on
if((diff1+diff2+diff3+diff4)>1)
continue;
if(diff1 == 1)
o1.opt1 = o1.opt1 + o2.opt1;
//and so on...
list.remove(j--);
}
}
public static <T> List<T> findByMultipleValue(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(filter).collect(Collectors.toList());
}
public static List<Options> getEqualOptionsList(List<Options> optList, Options opt){
return findByMultipleValue(optList, o -> o.hasSameOptions(opt));
}
现在,数据是重复的,可以合并。比如:
12 : 45 : AB = 12
12 : 45 : AB = 3
12 : 45 : AB = 4
这实际上意味着:12:45:AB=1234
因此,我要做的是将字符串分开,只得到结果中的单个值,例如:
1 : 4 : A = 12
1 : 4 : B = 12
1 : 5 : A = 12
//and so on.
1 : 2 : A = 12
1 : 3 : A = 12
-> 1 : 23 : A = 12
我将所有这些值列成一个列表,然后再次尝试组合它们以获得更有效的列表
我要做的第一步是获取所有具有相同选项但结果不同的对象,然后合并结果。事情是这样的:
Class Options{
String opt1;
String opt2;
String opt3;
String optResult;
//and some other stuff
boolean hasSameOptions(Options o){
return opt1.equals(o.opt1) && opt2.equals(o.opt2) && opt3.equals(o.opt3);
}
public void AddOptions(String options) {
for (String s : options.split("")) {
if (!optResult.contains(s)) {
optResult = optResult + s;
}
}
}
}
public static List<Options> cleanList(List<Options> oldList) {
List<Options> newList = new ArrayList<>();
for (Options item : oldList) {
Options temp = findEqualOptions(newList, item);
if (temp != null)
temp.AddOptions(item.optResult);
else
newList.add(item);
}
return newList;
}
public static <T> T findByProperty(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(Objects::nonNull).filter(filter).findFirst().orElse(null);
}
public static Options findEqualOptions(List<Options> list, Options opt) {
return findByProperty(list, d -> d.hasSameOptions(opt));
}
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
Option o1 = list.get(i);
Option o2 = list.get(j);
int diff1 = 0;
int diff2 = 0;
int diff3 = 0;
int diff4 = 0;
if(!o1.opt1.equals(o2.opt1))
diff1 = 1;
if(!o1.opt2.equals(o2.opt2))
diff2 = 1;
//and so on
if((diff1+diff2+diff3+diff4)>1)
continue;
if(diff1 == 1)
o1.opt1 = o1.opt1 + o2.opt1;
//and so on...
list.remove(j--);
}
}
public static <T> List<T> findByMultipleValue(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(filter).collect(Collectors.toList());
}
public static List<Options> getEqualOptionsList(List<Options> optList, Options opt){
return findByMultipleValue(optList, o -> o.hasSameOptions(opt));
}
我是这样做的:
Class Options{
String opt1;
String opt2;
String opt3;
String optResult;
//and some other stuff
boolean hasSameOptions(Options o){
return opt1.equals(o.opt1) && opt2.equals(o.opt2) && opt3.equals(o.opt3);
}
public void AddOptions(String options) {
for (String s : options.split("")) {
if (!optResult.contains(s)) {
optResult = optResult + s;
}
}
}
}
public static List<Options> cleanList(List<Options> oldList) {
List<Options> newList = new ArrayList<>();
for (Options item : oldList) {
Options temp = findEqualOptions(newList, item);
if (temp != null)
temp.AddOptions(item.optResult);
else
newList.add(item);
}
return newList;
}
public static <T> T findByProperty(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(Objects::nonNull).filter(filter).findFirst().orElse(null);
}
public static Options findEqualOptions(List<Options> list, Options opt) {
return findByProperty(list, d -> d.hasSameOptions(opt));
}
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
Option o1 = list.get(i);
Option o2 = list.get(j);
int diff1 = 0;
int diff2 = 0;
int diff3 = 0;
int diff4 = 0;
if(!o1.opt1.equals(o2.opt1))
diff1 = 1;
if(!o1.opt2.equals(o2.opt2))
diff2 = 1;
//and so on
if((diff1+diff2+diff3+diff4)>1)
continue;
if(diff1 == 1)
o1.opt1 = o1.opt1 + o2.opt1;
//and so on...
list.remove(j--);
}
}
public static <T> List<T> findByMultipleValue(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(filter).collect(Collectors.toList());
}
public static List<Options> getEqualOptionsList(List<Options> optList, Options opt){
return findByMultipleValue(optList, o -> o.hasSameOptions(opt));
}
for(int i=0;i1)
继续;
if(diff1==1)
o1.opt1=o1.opt1+o2.opt1;
//等等。。。
删除(j-);
}
}
我这样做,直到没有更多的变化。它工作得很好,但速度很慢。尤其是cleanList()方法。
有人知道如何让它变得更好吗?我尝试使用流直接获得整个equals选项列表,如下所示:
Class Options{
String opt1;
String opt2;
String opt3;
String optResult;
//and some other stuff
boolean hasSameOptions(Options o){
return opt1.equals(o.opt1) && opt2.equals(o.opt2) && opt3.equals(o.opt3);
}
public void AddOptions(String options) {
for (String s : options.split("")) {
if (!optResult.contains(s)) {
optResult = optResult + s;
}
}
}
}
public static List<Options> cleanList(List<Options> oldList) {
List<Options> newList = new ArrayList<>();
for (Options item : oldList) {
Options temp = findEqualOptions(newList, item);
if (temp != null)
temp.AddOptions(item.optResult);
else
newList.add(item);
}
return newList;
}
public static <T> T findByProperty(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(Objects::nonNull).filter(filter).findFirst().orElse(null);
}
public static Options findEqualOptions(List<Options> list, Options opt) {
return findByProperty(list, d -> d.hasSameOptions(opt));
}
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
Option o1 = list.get(i);
Option o2 = list.get(j);
int diff1 = 0;
int diff2 = 0;
int diff3 = 0;
int diff4 = 0;
if(!o1.opt1.equals(o2.opt1))
diff1 = 1;
if(!o1.opt2.equals(o2.opt2))
diff2 = 1;
//and so on
if((diff1+diff2+diff3+diff4)>1)
continue;
if(diff1 == 1)
o1.opt1 = o1.opt1 + o2.opt1;
//and so on...
list.remove(j--);
}
}
public static <T> List<T> findByMultipleValue(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(filter).collect(Collectors.toList());
}
public static List<Options> getEqualOptionsList(List<Options> optList, Options opt){
return findByMultipleValue(optList, o -> o.hasSameOptions(opt));
}
公共静态列表findByMultipleValue(集合列、谓词筛选器){
返回col.stream().filter(filter.collect(Collectors.toList());
}
公共静态列表GetEqualOptions列表(列表选项列表,选项选项){
返回findByMultipleValue(optList,o->o.hasameOptions(opt));
}
但这让它慢了很多
附:这不是完整的代码,只是我想做的一个例子。我希望这一次更容易理解:)可能不是最优雅或最佳的解决方案,但这里已经有一个快速的方法,根据您的描述给出结果。它使用@Joseph Larson评论中建议的HashMap 我选择了一组字符,以确保其中的值不重复,但可以随意调整:)
编辑:遗漏了问题的一部分,更新以在差异接近时添加合并。就优化而言,这一部分可能比第一部分更糟糕,但它是一个有效的基础:)可能不是最优雅或最佳的解决方案,但这里已经有了一个快速方法,可以根据您的描述给出结果。它使用@Joseph Larson评论中建议的HashMap 我选择了一组字符,以确保其中的值不重复,但可以随意调整:)
编辑:遗漏了问题的一部分,更新以在差异接近时添加合并。就优化而言,这一部分可能比第一部分更糟糕,但它是一个有效的基础:)可能将每个“等式”的左侧表示为字符串,就像它所写的一样,并将其存储在散列中,其中散列中的值是组合的可能结果。所以你读了第一个,从LHS中提取字符串,发现它不在你的散列中,所以添加它。下次点击相同的LHS时,您将获取现有值并附加新值,而不是添加。散列查找非常快,所以在这一部分您将得到O(n)@JosephLarson感谢tipp!可能将每个“等式”的左侧表示为一个字符串,非常类似于所写的字符串,并将其存储在散列中,其中散列中的值是组合的可能结果。所以你读了第一个,从LHS中提取字符串,发现它不在你的散列中,所以添加它。下次点击相同的LHS时,您将获取现有值并附加新值,而不是添加。散列查找非常快,所以在这一部分您将得到O(n)@JosephLarson感谢tipp!你错过了左边的字符串被分解成核心元素来做单个语句的部分,我编辑了我的帖子,因为我觉得看到它不是很好。我用你的解决方案“只是”清理列表方法和它的地狱快了很多,仍然需要在我的实施工作一点,但非常感谢!你错过了左边的字符串被分解成核心元素来做单个语句的部分,我编辑了我的帖子,因为我觉得看到它不是很好。我用你的解决方案“只是”清理列表方法和它的地狱快了很多,仍然需要在我的实施工作一点,但非常感谢!