Java中两个ArrayList的内部联接

Java中两个ArrayList的内部联接,java,arraylist,Java,Arraylist,有没有一种方法可以基于一个字段对两个不同对象的两个ArrayList进行内部联接 假设我有: ArrayList<Car> ArrayList<Owner> ArrayList ArrayList 汽车将具有以下属性:重量、最高速度、车主ID 所有者将具有以下属性:姓名、年龄、Id 结果将是一个带有属性的ArrayList,Weight、Top speed、Id、Name、Age 我想基于一个名为Id的字段对这两个变量进行内部联接。没有数据库或嵌套循环,有什么最佳方法

有没有一种方法可以基于一个字段对两个不同对象的两个ArrayList进行内部联接

假设我有:

ArrayList<Car>
ArrayList<Owner>
ArrayList
ArrayList
汽车将具有以下属性:
重量、最高速度、车主ID

所有者将具有以下属性:
姓名、年龄、Id

结果将是一个带有属性的
ArrayList
Weight、Top speed、Id、Name、Age


我想基于一个名为
Id
的字段对这两个变量进行内部联接。没有数据库或嵌套循环,有什么最佳方法可以做到这一点吗?

如果您只需要两个数组的交集,您只需要在一个列表上循环,当您在另一个列表中找到与当前循环元素ID匹配的元素时,将其放在第三个列表上(您想要保存交集元素的那一个)

您认为它不可能,尤其是ArrayList只能包含一种类型(或子类型/实现类)。但是,使用另一种数据结构可以通过对象的ID映射对象,这可能是一种解决方案

HashMap<Integer, HashMap<Car, Owner>> map;
它将作为HashMap实例返回,包含一辆车作为钥匙,一个所有者作为共同响应值,两者都应该具有id 10。但这不是隐式的,您必须通过创建地图来确保这一点

此外,您还可以编写一个“映射”内部联接的类:

public class CarToOwner() {
     private Car car;
     private Owner owner;
}
编辑: 如果您有一个包含汽车和车主的类,它会直接映射它们之间的关系。在创建CarToOwner类的实例时,您必须确保这两种类型的id与它们之间的连接相同

事实上,这并不是一个真正干净的解决方案,我只想用它作为在GUI中显示表的“快速而肮脏”的方法

编辑:
对于拥有多个车主的汽车或拥有多辆汽车的车主,有必要将属性存储在CarToOwner的列表中或创建多个CarToOwner实例。

首先迭代
列表
(您应该使用接口而不是实现),并在
映射中添加每个元素(我假设ID是唯一的)

然后迭代
列表
,并将结果存储在
列表
中。当然,您将需要一个构造函数来获得一辆车和一位车主的结果

此处没有嵌套循环:)

您可以使用方法

您必须以一种特殊的方式(参见下面的代码)在Car和Owner类中实现equals方法

例如,假设Car和Owner类都有一个字符串id属性,则代码为:

public static void main(String[] args) {        
    ArrayList<Car> list1 = new ArrayList<Car>();
    list1.add(new Car("ID1"));
    list1.add(new Car("ID2"));
    list1.add(new Car("ID3"));


    ArrayList<Owner> list2 = new ArrayList<Owner>();
    list2.add(new Owner("ID1"));
    list2.add(new Owner("ID3"));
    list2.add(new Owner("ID4"));

    list1.retainAll(list2);
    System.out.println(list1);
}

static class Car
{
    public Car(String id)
    {
        super();
        this.id = id;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;

        if (obj instanceof Owner)
        {
            Owner other = (Owner) obj;
            if (id == null)
            {
                if (other.id != null)
                    return false;
            }
            else if (!id.equals(other.id))
                return false;
        }
        else if (obj instanceof Car)
        {
            Car other = (Car) obj;
            if (id == null)
            {
                if (other.id != null)
                    return false;
            }
            else if (!id.equals(other.id))
                return false;
        }
        return true;
    }

    @Override
    public String toString()
    {
        return "Car [id=" + id + "]";
    }

    public String id;
}

static class Owner
{
    public Owner(String id)
    {
        super();
        this.id = id;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (obj instanceof Owner)
        {
            Owner other = (Owner) obj;
            if (id == null)
            {
                if (other.id != null)
                    return false;
            }
            else if (!id.equals(other.id))
                return false;
        }
        else if (obj instanceof Car)
        {
            Car other = (Car) obj;
            if (id == null)
            {
                if (other.id != null)
                    return false;
            }
            else if (!id.equals(other.id))
                return false;
        }


        return true;
    }

    @Override
    public String toString()
    {
        return "Owner [id=" + id + "]";
    }

    public String id;
}
publicstaticvoidmain(字符串[]args){
ArrayList list1=新的ArrayList();
列表1.添加(新车(“ID1”);
列表1.添加(新车(“ID2”);
列表1.添加(新车(“ID3”);
ArrayList list2=新的ArrayList();
清单2.添加(新所有者(“ID1”);
清单2.添加(新所有者(“ID3”);
清单2.添加(新所有者(“ID4”);
清单1.保留(清单2);
System.out.println(列表1);
}
静态级轿车
{
公共汽车(字符串id)
{
超级();
this.id=id;
}
@凌驾
公共布尔等于(对象obj)
{
if(this==obj)
返回true;
if(obj==null)
返回false;
if(所有者的obj实例)
{
业主其他=(业主)obj;
if(id==null)
{
if(other.id!=null)
返回false;
}
如果(!id.equals(other.id))
返回false;
}
else if(车辆的obj实例)
{
汽车其他=(汽车)obj;
if(id==null)
{
if(other.id!=null)
返回false;
}
如果(!id.equals(other.id))
返回false;
}
返回true;
}
@凌驾
公共字符串toString()
{
返回“Car[id=“+id+”]”;
}
公共字符串id;
}
静态类所有者
{
公共所有者(字符串id)
{
超级();
this.id=id;
}
@凌驾
公共布尔等于(对象obj)
{
if(this==obj)
返回true;
if(obj==null)
返回false;
if(所有者的obj实例)
{
业主其他=(业主)obj;
if(id==null)
{
if(other.id!=null)
返回false;
}
如果(!id.equals(other.id))
返回false;
}
else if(车辆的obj实例)
{
汽车其他=(汽车)obj;
if(id==null)
{
if(other.id!=null)
返回false;
}
如果(!id.equals(other.id))
返回false;
}
返回true;
}
@凌驾
公共字符串toString()
{
返回“所有者[id=“+id+”]”;
}
公共字符串id;
}
输出将是:

[Car[id=ID1],Car[id=ID3]]


显然,在这种情况下,您将有一个Car列表,如果您想要另一种类型,您可以确保两个类都继承自同一个超类,或者您可以确保两个类实现相同的接口,然后管理该接口类型。

假设
Id
的类型实现了
可比的

首先,对列表进行排序,使
Id
s按升序排列:

Collections.sort(cars, new Comparator<Car>() {
  @Override public int compare(Car a, Car b) {
    return a.OwnerId.compareTo(b.OwnerId);
  }
});
Collections.sort(owners, new Comparator<Owner>() {
  @Override public int compare(Owner a, Owner b) {
    return a.Id.compareTo(b.Id);
  }
});
然后跳过所有具有较小
Id
s的
Owner
实例:

  while (oi < owners.size() && owners.get(oi).Id.compareTo(idStart) < 0) {
    ++oi;
  }
最后,对ID相同的车辆/车主对执行以下操作:

  for (Car car : carsWithId) {
    for (Owner owner : ownersWithId) {
      System.out.println(car + ", " + owner);
    }
  }
}
假设你:

  • 使用Java8
  • 您有
    列出车辆
    列出车主
  • Result
    具有一个构造函数,该构造函数接受一辆
    汽车
    和一位
    车主
这个我
  Id idStart = cars.get(ci).OwnerId;
  int carStart = ci;
  while (ci < cars.size() && cars.get(ci).OwnerId.equals(idStart)) {
    ++ci;
  }
  List<Car> carsWithId = cars.subList(carStart, ci);
  while (oi < owners.size() && owners.get(oi).Id.compareTo(idStart) < 0) {
    ++oi;
  }
  int ownerStart = oi;
  while (oi < owners.size() && owners.get(oi).Id.equals(idStart)) {
    ++oi;
  }
  List<Owner> ownersWithId = owners.subList(ownerStart, oi);
  for (Car car : carsWithId) {
    for (Owner owner : ownersWithId) {
      System.out.println(car + ", " + owner);
    }
  }
}
final Map<Integer, Owner> ownersById = owners.stream()
   .collect(Collectors.toMap(k -> k.id, k -> k));
final List<Result> results = cars.stream()
   .map(car -> new Result(car, ownersById.get(car.OwnerId)))
   .collect(Collectors.toList());