请我尝试通过两个独特的属性过滤我从DB查询的列表。以下是该表的示例:
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();
}
但这不能正确过滤。我只能得到像时间和时间这样的独特价值观。类型是平等的。任何有助于我解决这个问题的想法都是受欢迎的。
答案 0 :(得分:0)
由于您希望按唯一的time
和type
字段进行过滤,因此我引入了一个字符串,可以将其读作
<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);
}
}
答案 1 :(得分:0)
您必须对存储在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);
}
答案 2 :(得分:0)
我不知道,也许不是你想要的,但是你可以使用 HashSet 代替ArrayList,在java中这个数据结构默认不插入副本。当然,这种机制仅适用于基本类型,对于自定义对象(作为您的),您应该覆盖哈希码,并使用等于方法来使机制起作用。
以下是您的案例示例:
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)实现了Comparable,这意味着你将覆盖方法compareTo(Object o)
,而不是HashSet,你可以使用 TreeSet ,你将获得均匀的排序数据结构
答案 3 :(得分:0)
这可以使用流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}