2013-10-03 55 views
0

集合想象一下下面的對象過濾和轉化使用谷歌番石榴

class Trip { 
    String name; 
    int numOfTravellers; 
    DateMidnight from; 
    DateMidnight too; 
} 

我寫了一個手動遞歸濾波和Java的變換方法。不過,我認爲這可以使用谷歌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

我認爲迭代和遞歸的組合肯定會降低可讀性。也許你可以在這裏只用一個for循環來使用地圖。列表中的每個元素都會進入地圖或與地圖中的值結合使用。 –

回答

2

我不認爲番石榴可以幫助很多這裏都是平等的那些組合。還有很多可以提高離不開它:

創建TripKey {String name; int numOfTravellers;},定義equals,並用它來代替你的名不副實areEqual的。將你的旅程按鍵分成列表 - 這裏ListMultimap<TripKey, Trip>可以提供幫助。

對每個鍵,根據from排序相應的列表。嘗試將每次旅行與以下所有行程結合起來。如果它合併,只重新啓動內部循環。這應該已經比你的解決方案更清晰(並且更快)...所以我在這裏停下來。

2

我只是使用一個HashSet。

首先在您的旅行對象中定義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;