通过两个唯一属性进行过滤Java列表



请我尝试过滤一个我从数据库查询的列表,该列表通过两个唯一的属性。这是表的样本:

id | seatNo | time | type
=== ======== ====== =====
1  |   1    |   1  |  1  *
2  |   2    |   1  |  1
3  |   1    |   2  |  1  *
4  |   2    |   2  |  1
5  |   3    |   1  |  2  *
6  |   4    |   1  |  2

带有星号(*(的线是时间和类型的唯一值。我如何编写一个循环,该循环通过时间和类型来过滤此列表以换取唯一对象。我尝试了这样的事情:

int currentTime = 0;
int currentType = 0;
List<Bus> sortedBuses = new ArrayList<>();
for (Bus bus : allSeats) {
    if (bus.getTime()!= currentTime && bus.getType != currentType) {
        sortedBuses.add(bus);
    }
    currentId = bus.getTime();
    currentType = bus.getType();
}

但这无法正确过滤。我只能获得独特的价值,例如时间&amp;类型相等。任何可以帮助我解决的想法都受到欢迎。

您必须对 sortedBuses

中存储的公共汽车进行过滤
List<Bus> sortedBuses = new ArrayList<Bus>();
outerloop:
for (Bus bus : allSeats) {
   for (Bus sorted : sortedBuses)
      if (bus.getTime()==sorted.getTime() && bus.getType == sorted.getType)
        continue outerloop;
   sortedBuses.add(bus);
}

由于您想通过唯一的timetype字段过滤,因此我引入了一个可以读为

的字符串
<time>_<type>

然后,找到唯一元素更容易:

List<String> foundTimeType = new ArrayList<String>(); // represents a list of known types
List<Bus> sortedBuses = new ArrayList<>();
for (Bus bus : allSeats) {
    String timeType = "" + bus.getTime() + "_" + bus.getType();
    // only add if timeType is not present in foundTimeType list
    if (! foundTimeType.contains(timeType)) {
        foundTimeType.add(timeType); // to keep it unique
        sortedBuses.add(bus);
    }
}

我不知道,也许不是您想要的,但是您可以使用 hashset ,而不是ArrayList,在Java中,此数据结构没有默认情况下插入重复。当然,此机制仅适用于原始类型,对于自定义对象(作为您的(,您应该覆盖hashcode并等于使该机制起作用的方法。

在这里,您的案例示例:

public class Bus {
    private int type;
    private int time;
    public Bus(int type, int time) {
        // TODO Auto-generated constructor stub
            this.type = type;
            this.time = time;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    public int getTime() {
        return time;
    }
    public void setTime(int time) {
        this.time = time;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + time;
        result = prime * result + type;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Bus other = (Bus) obj;
        if (time != other.time)
            return false;
        if (type != other.type)
            return false;
        return true;
    }
}

,您的主要是:

import java.util.HashSet;

public class Main {
    public Main() {
        // TODO Auto-generated constructor stub
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        HashSet<Bus> buses = new HashSet<Bus>();
        Bus b1 = new Bus(1, 1);
        Bus b2 = new Bus(1, 1);
        Bus b3 = new Bus(2, 1);
        Bus b4 = new Bus(2, 1);
        buses.add(b1);
        buses.add(b2);
        buses.add(b3);
        buses.add(b4);
        System.out.println("size: "+buses.size());
 for(Bus bus : buses) {
            System.out.println(bus.getTime()+" "+bus.getType());
            }

    }
}

输出:

size: 2
1 1
1 2

此外,如果您的对象(BUS(实现可比性,则意味着您将覆盖方法compareTo(Object o),而不是标签,您可以使用 treeTETET ,甚至可以获得数据结构。

可以使用流API在一条线上求解,通过将时间和键入映射的键,然后简单地导出值来解决。钥匙将包含时间和键入。

行将是:

buses.stream().collect(toMap(b -> String.format("%d_%d", b.getType(), b.getTime()), p -> p, (p, q) -> p))
                    .values();

这是一个简单的测试:

List<Bus> buses = Arrays.asList(new Bus(1, 1, 1), new Bus(2, 1, 1),
                new Bus(3, 2, 1), new Bus(4, 2, 1),
                new Bus(5, 1, 2), new Bus(6, 1, 2));
Collection<Bus> res = buses.stream().collect(toMap(b -> String.format("%d_%d", b.getType(), b.getTime()), p -> p, (p, q) -> p))
                .values();
res.forEach(System.out::println);

这在控制台上打印出来:

> Bus{id=1, type=1, time=1}
> Bus{id=5, type=1, time=2}
> Bus{id=3, type=2, time=1}

最新更新