Java 如果属性相等,则合并并删除

Java 如果属性相等,则合并并删除,java,Java,下面是我的代码(可以使用-ea作为命令行选项进行复制粘贴) 我有一个名为Main的对象。我在列表中有Main。如果两个属性(a和b)等于列表中的另一个Main对象,则应连接属性字符串。此外,应删除重复项(当两个属性相等时)(因此列表不能包含两个或多个干线,其中a和b相同) 我用一个HashMap,hashCode,试过了,但我想不出来。注意:我使用OpenJDK-12,不能使用更新的版本 import java.util.ArrayList; import java.util.List; imp

下面是我的代码(可以使用
-ea
作为命令行选项进行复制粘贴)

我有一个名为
Main
对象。我在
列表中有
Main
。如果两个属性(
a
b
)等于
列表中的另一个
Main
对象,则应连接属性
字符串。此外,应删除重复项(当两个属性相等时)(因此
列表
不能包含两个或多个
干线
,其中
a
b
相同)

我用一个
HashMap
hashCode
,试过了,但我想不出来。注意:我使用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);
    }
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.Objects;
公共班机{
最终INTA;
最终int b;
最终列表字符串;
Main(int a、int b、列表字符串){
这个a=a;
这个.b=b;
this.strings=字符串;
}
专用静态主生成器main0(){
返回新的Main(0,1,createListWithOneElement(“将我与main1合并”);
}
公共静态void main(字符串[]args){
main0=generateMain0();
Main main1=新的Main(0,1,createListWithOneElement(“将我与main2合并”);
Main Main 2=新的Main(0,2,createListWithOneElement(“别管我”);
Main Main 3=新的Main(0,2,createListWithOneElement(“也别管我”);
列表mains=newarraylist();
主电源。添加(主电源0);
主管道。添加(主管道1);
主管道。添加(主管道2);
主管道。添加(主管道3);
//在这里使用魔术删除重复和concat属性字符串
//应删除main1,因为属性a和b等于main0属性a和b
断言mains.size()==3;
Main main0Copy=generateMain0();
main0Copy.strings.add(“将我与main2合并”);
//第一个元素应该是main0。它还应该包含
//main1的字符串,因为属性a和b相等
断言mains.get(0).equals(main0Copy);
断言mains.get(1).equals(main2);
断言mains.get(2).equals(main3);
}
私有静态列表createListWithOneElement(字符串值){
列表l=新的ArrayList();
l、 增加(价值);
返回l;
}
@凌驾
公共布尔等于(对象o){
如果(this==o)返回true;
如果(o==null | | getClass()!=o.getClass())返回false;
Main=(Main)o;
返回a==main.a&&
b==main.b&&
strings.equals(main.strings);
}
@凌驾
公共int hashCode(){
返回Objects.hash(a,b,strings);
}
}

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

在内部,它使用
列表
映射
的组合来确定
a
b
的组合是否已添加到“列表”中。如果是,则将给定的
Main
的所有
字符串添加到现有的
Main
。如果没有,它会将给定的
Main
添加到列表中

包示例;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
公共类主列表{
私人最终清单;
私有最终地图查找;
公共MainList(){
this.mains=新的ArrayList();
this.lookup=newhashmap();
}
公共主get(int索引){
返回此.mains.get(索引);
}
公共无效添加(主){
最终键=新键(main.a,main.b);
Main existingMain=this.lookup.get(key);
if(existingMain==null){
此.main.add(main);
this.lookup.put(key,main);
}否则{
existingMain.strings.addAll(main.strings);
}
}
公共空间移除(主){
最终键=新键(main.a,main.b);
Main existingMain=this.lookup.get(key);
if(existingMain!=null){
if(existingMain.equals(main)){
本.干线.拆除(现有干线);
此.lookup.remove(键);
}否则{
existingMain.strings.removeAll(main.strings);
}
}
}
公共无效删除(整型索引){
最终主管道拆除主管道=此主管道拆除(索引);
最终密钥=新密钥(removedMain.a,removedMain.b);
此.lookup.remove(键);
}
公共整数大小(){
返回此.mains.size();
}
私有静态类密钥{
私人终审法院;
私人最终int b;
私钥(inta,intb){
这个a=a;
这个.b=b;
}
@凌驾
公共布尔等于(对象){
if(this==对象){
返回true;
}else if(object==null | | getClass()!=object.getClass()){
返回false;
}
Key=(Key)对象;
返回this.a==key.a&&this.b==key.b;
}
@凌驾
公共int hashCode(){
返回31*this.a+31*this.b;
}
}
}

(请注意您的第一个
assert
):
List
s不是
Set
s,它们不会删除insert@codeflush.dev是的,我知道,在“DoMagic”注释中,我希望代码能够过滤掉,如果2条干线同时具有a和b相等性。将其设置为一个集合也不起作用,因为对Main实现hashcode/equals的方式(我不想仅用属性a和b覆盖equals)是否允许使用自定义的
列表
-Implementation?@codeflush.dev yes,我使用的是Open-JDK-12,不能使用更新的版本。您是否需要
java.util.List
的实现,或者它是一个完全定制的实现,可以做什么