首页 > 解决方案 > 如果属性相等则合并并删除

问题描述

下面是我的代码(可以使用命令行选项复制粘贴到https://www.compilejava.net/中)。-ea

我有一个ObjectMain. 我Main里面有一个List. 如果 2 个属性 (a和) 与 ,中的另一个对象b相等,则应该连接属性。此外,应该删除重复项(当 2 个属性相等时)(因此不能包含 2 个或更多,其中两者和相同)。MainliststringslistMainsab

我用 , 试过了HashMaphashCode但我无法弄清楚。注意:我使用的是 OpenJDK-12,不能使用较新的版本。

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

public class Main {

    final int a;
    final int b;
    final List<String> strings;

    Main(int a, int b, List<String> strings) {
        this.a = a;
        this.b = b;
        this.strings = strings;
    }

    private static Main generateMain0() {
        return new Main(0, 1, createListWithOneElement("merge me with main1"));
    }

    public static void main(String[] args) {
        Main main0 = generateMain0();
        Main main1 = new Main(0, 1, createListWithOneElement("merge me with main2"));
        Main main2 = new Main(0, 2, createListWithOneElement("leave me alone"));
        Main main3 = new Main(0, 2, createListWithOneElement("leave me alone also"));

        List<Main> mains = new ArrayList<>();

        mains.add(main0);
        mains.add(main1);
        mains.add(main2);
        mains.add(main3);

        // Do magic here to remove duplicate and concat property strings

        // main1 should be removed, since property a and b were equal to main0 property a and b
        assert mains.size() == 3;

        Main main0Copy = generateMain0();

        main0Copy.strings.add("merge me with main2");

        // The first element should be main0. It should also contain
        // the strings of main1 since property a and b were equal
        assert mains.get(0).equals(main0Copy);
        assert mains.get(1).equals(main2);
        assert mains.get(2).equals(main3);
    }

    private static List<String> createListWithOneElement(String value) {
        List<String> l = new ArrayList<>();

        l.add(value);

        return l;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Main main = (Main) o;
        return a == main.a &&
                b == main.b &&
                strings.equals(main.strings);
    }

    @Override
    public int hashCode() {
        return Objects.hash(a, b, strings);
    }
}

标签: java

解决方案


如果正如您在评论中所说,您可以使用完全自定义的List,您可以尝试下面的代码。

在内部,它使用 aList和 a的组合来确定和Map的组合是否已经添加到“列表”中。如果是,它将所有给定的内容添加到现有的. 如果没有,它会添加给定的列表。abstringsMainMainMain

package example;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainList {

    private final List<Main> mains;
    private final Map<Key, Main> lookup;

    public MainList() {
        this.mains = new ArrayList<>();
        this.lookup = new HashMap<>();
    }

    public Main get(int index) {
        return this.mains.get(index);
    }

    public void add(Main main) {
        final Key key = new Key(main.a, main.b);
        Main existingMain = this.lookup.get(key);

        if (existingMain == null) {
            this.mains.add(main);
            this.lookup.put(key, main);
        } else {
            existingMain.strings.addAll(main.strings);
        }
    }

    public void remove(Main main) {
        final Key key = new Key(main.a, main.b);
        Main existingMain = this.lookup.get(key);

        if (existingMain != null) {
            if (existingMain.equals(main)) {
                this.mains.remove(existingMain);
                this.lookup.remove(key);
            } else {
                existingMain.strings.removeAll(main.strings);
            }
        }
    }

    public void remove(int index) {
        final Main removedMain = this.mains.remove(index);
        final Key key = new Key(removedMain.a, removedMain.b);

        this.lookup.remove(key);
    }

    public int size() {
        return this.mains.size();
    }

    private static class Key {

        private final int a;
        private final int b;

        private Key(int a, int b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public boolean equals(Object object) {
            if (this == object) {
                return true;
            } else if (object == null || getClass() != object.getClass()) {
                return false;
            }
            Key key = (Key) object;
            return this.a == key.a && this.b == key.b;
        }

        @Override
        public int hashCode() {
            return 31 * this.a + 31 * this.b;
        }
    }
}


推荐阅读