Java 组合几乎相等的数据列表的值

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;

所以我以前问过,但我似乎不太清楚我在说什么,所以我现在想说得更清楚: 我要做的是为导入准备数据。我得到的数据是人为的,效率不高,所以我删除了不必要的条目,并尽可能多地合并数据

它的功能类似于配置程序。我得到的数据如下所示:

123:45:AB=12 这意味着:如果选项1是1或2或3,选项2是4或5,选项3是A或B,结果将是1和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;
            }
        }
    }

}
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!你错过了左边的字符串被分解成核心元素来做单个语句的部分,我编辑了我的帖子,因为我觉得看到它不是很好。我用你的解决方案“只是”清理列表方法和它的地狱快了很多,仍然需要在我的实施工作一点,但非常感谢!你错过了左边的字符串被分解成核心元素来做单个语句的部分,我编辑了我的帖子,因为我觉得看到它不是很好。我用你的解决方案“只是”清理列表方法和它的地狱快了很多,仍然需要在我的实施工作一点,但非常感谢!