想象一下以下对象
class Trip {
String name;
int numOfTravellers;
DateMidnight from;
DateMidnight too;
}
我在java中编写了一个手动递归过滤器和转换方法。但是,我认为使用Google Guava可以更有说服力地写出来。
有人可以帮助我并告诉我如何重写这些以使其更具可读性吗?
基本上这个方法的作用是找到相同的条目,并通过改变日期字段来组合相同的条目
List<Trip> combineEqual(List<Trip> list) {
int n = list.size() - 1;
for (int i = n; i >= 0; i--) {
for (int j = n; j >= 0; j--) {
if (i == j) {
continue;
}
if (shouldCombineEqual(list.get(i), list.get(j))) {
Trip combined = combine(list.get(i), list.get(j));
list.remove(i);
list.remove(j);
list.add(Math.min(i, j), combined);
return combineEqual(liste);
}
}
}
return list;
}
private boolean shouldCombineEqual(Trip a, Trip b) {
return shouldCombineWith(a, b) || shouldCombineWith(b, a);
}
private boolean shouldCombineWith(Trip a, Trip b) {
return a.too() != null
&& a.too().plusDays(1).equals(b.from)
&& areEqual(a, b);
}
private boolean areEqual(Trip a, Trip b) {
return equal(a.name,b.name) && equal(a.numOfTravellers, b.numOfTravellers);
}
private boolean equal(Object a, Object b) {
return a == null && b == null || a != null && a.equals(b);
}
private Trip combineEqual(Trip a, Trip b) {
Trip copy = copy(a); //Just a copy method
if (a.from.isAfter(b.from)) {
Trip tmp = a;
a = b;
b = tmp;
} // a is now the one with the earliest too date
copy.from = a.from;
copy.too = b.too;
return copy;
}
答案 0 :(得分:2)
我不认为番石榴在这里可以提供很多帮助。如果没有它,你可以做很多改进:
创建TripKey {String name; int numOfTravellers;}
,定义equals
,然后使用它而不是错误的areEqual
。通过按键将行程拆分为列表 - ListMultimap<TripKey, Trip>
可以提供帮助。
对于每个键,根据from
对相应的列表进行排序。尝试将每次旅行与以下所有旅行结合起来。如果它合并,只重新启动内部循环。这应该比你的解决方案更清晰(也更快)......所以我就此止步。
答案 1 :(得分:2)
我只是使用HashSet。
首先在trip对象中定义equals和hashcode。将第一个列表添加到集合中。然后遍历第二个列表,检查匹配的行程是否已经在集合中。类似的东西:
public static Set<Trip> combineEquals(List<Trip> 11, List<Trip> 12) {
Set<Trip> trips = new HashSet<>(11);
for ( Trip t: 12) {
if ( trips.contains(t)) {
// combine whats in the set with t
} else {
trips.add(t);
}
}
return trips;