【发布时间】:2019-07-16 04:41:14
【问题描述】:
所以我之前问过,但似乎我对我在说什么还不够清楚,所以我现在试图让它更清楚: 我想做的是为导入准备数据。我得到的数据是人为的,效率不高,所以我删除了不必要的条目并尽可能地组合数据。
它用于配置器之类的东西。我得到的数据看起来像这样:
123 : 45 : AB = 12 这意味着:如果选项 1 是 1 OR 2 OR 3,选项 2 是 4 OR 5,选项 3 是 A OR B,则结果将为 1 AND 2
我创建了一个类似这样的类:
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;
}
}
}
}
现在,数据是重复的,可以合并。喜欢:
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.
我列出所有这些值,然后尝试再次组合它们以获得更有效的列表。
我要做的第一步是获取所有具有相同选项但结果不同的对象并组合结果。事情是这样的:
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));
}
在那之后,我尝试通过组合只有一个不同值的元素来进一步压缩列表。例如:
1 : 2 : A = 12
1 : 3 : A = 12
-> 1 : 23 : A = 12
我是这样做的:
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--);
}
}
我会一直这样做,直到没有更多更改为止。它运作良好,但缓慢。尤其是方法 cleanList()。 有人知道如何让它变得更好吗?我尝试使用流来直接获取等于选项的整个列表,如下所示:
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));
}
但这让它慢了很多。
附言。 :它不是完整的代码,只是我试图做的一个例子。我希望这次更容易理解:)
【问题讨论】:
-
也许将每个“等式”的左侧表示为一个字符串,就像它所写的一样,并将其存储在散列中,其中散列中的值是组合的可能结果。所以你会阅读第一个,从 LHS 中提取字符串,发现它不在你的哈希中,所以添加它。下次您点击相同的 LHS 时,您将获取现有值并附加新值,而不是添加。哈希查找非常快,所以你会在这部分得到 O(n)。
-
@JosephLarson 感谢您的提示!
标签: java list merge java-stream