Java中两个ArrayList的内部联接
有没有一种方法可以基于一个字段对两个不同对象的两个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<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());