2017-10-17 69 views
0

我有一個List集合,其中每個指標包含一些特性,如重複:metricName,命名空間,車隊,類型,組件,firstSeenTime,lastSeenTime等有此列表中重複這樣的除了firstSeenTime和lastSeenTime之外,所有屬性都是相同的。我正在尋找一種優雅的方式來過濾這個列表,並且只有在存在這樣的重複時才返回帶有最近lastSeenTime的度量標準。刪除基於幾個對象屬性從列表

東西比這更好:

private List<Metric> processResults(List<Metric metrics) { 
    List<Metric> results = new ArrayList<>(); 

    for (Metric incomingMetric: metrics) { 

     // We need to implement "contains" below so that only properties 
     // other than the two dates are checked. 
     if (results.contains(incomingMetric) { 
      int index = results.indexOf(incomingMetric); 
      Metric existing = results.get(index); 
      if (incomingMetric.getLastSeen().after(existing.getLastSeen())) { 
       results.set(index, metricName); 
      } else { 
       // do nothing, metric in results is already the latest 
      } 
     } else { 
      // add incomingMetric to results for the first time 
      results.add(incomingMetric); 
     } 
    } 

    return results; 
} 

的results.contains檢查通過結果遍歷所有的指標,如果每個對象除了兩個日期的屬性相匹配檢查完成。

這可能是一個更好的方法,這兩種優雅和性能?

回答

1

我不知道你是如何產生List<Metric>。但是,如果您可以維護Map<String, Metric>而不是該列表,則可以嘗試以下方法。

所以這圖的關鍵是需要比較這些值的組合。 (除了日期屬性。)

鍵:「{metricName} $ {}類型$ .....」

爲此,您可以保持與吸氣劑度量對象的另一個屬性。當你調用getter時,它將返回密鑰。

然後在放入地圖之前檢查鍵是否存在。如果它存在,則獲取該鍵的存儲的度量標準,然後執行日期比較以查找最新的度量標準對象。如果它是最新的,則用新對象替換地圖的存儲對象。

PS:對兩種情況執行時間比較。所以你會找到最好的方法。

+0

感謝。這看起來不錯,我使用一個靜態嵌套類來構造關鍵字(在將鍵構造爲字符串時不必處理字段分隔符),但是隻是一個字符串就足夠了。 – gansvv

0

在java中最優雅的方式來比較的東西是Comparator接口。

public List<Metric> removeDuplicates(List<Metric> metrics) { 

    List<Metric> copy = new ArrayList<>(metrics); 
    //first sort the metrics list from most recent to older 
    Collections.sort(copy, new SortComparator()); 

    Set<Metric> set = new TreeSet<Metric>(new Comparator<Metric>() { 

     @Override 
     public int compare(Metric o1, Metric o2) { 
      int result = 0; 
      // compare the two metrics given your rules 
      return result; 
     } 
    }); 

    for(Metric metric : copy) { 
     set.add(metric); 
    } 

    List<Metric> result = Arrays.asList(set.toArray()); 
    return result; 
} 

class SortComparator implements Comparator<Metric> { 

    @Override 
    public int compare(Metric o1, Metric o2) { 
     int result = 0; 
     if(o2.getLastSeenTime() != null && o1.getLastSeenTime() != null) { 
      result = o2.getLastSeenTime().compareTo(o1.getLastSeenTime()); 
     } 
     return result; 
    } 

} 

強這種方法的是,你可以寫一個系列的比較器,並提供一個Factory在運行時選擇比較您的指標,並刪除或不實例最好的辦法:你應該使用類似刪除重複作爲運行條件中的副本:

public void removeDuplicates(List<Metric> metrics, Comparator<Metric> comparator) { 

    List<Metric> copy = new ArrayList<>(metrics); 
    Collections.sort(copy, new SortComparator()); 

    Set<Metric> set = new TreeSet<Metric>(comparator); 
    for(Metric metric : copy) { 
     set.add(metric); 
    } 
    List<Object> result = Arrays.asList(set.toArray()); 
    return result; 
} 
+0

您正在維護TreeSet以避免重複的權利?那麼你怎麼知道該套件持有最新的公制?基本上,如何區分邏輯中最新的Metric和重複的Metric? – Neero

+0

謝謝。我會解決我的答案。 – Doleron

0

感謝您的答案。我採用了地圖方法,因爲它不會產生其他種類和副本。

@VisibleForTesting 
Set<Metric> removeDuplicates(List<Metric> metrics) { 

Map<RawMetric, Metric> metricsMap = new HashMap<>(); 
for (Metric metric : metrics) { 
    RawMetric rawMetric = RawMetric.builder() 
      .metricName(metric.getName()) 
      .metricType(metricName.getMetricType()) 
      ... // and more 
      .build(); 

     // pick the latest updated metric (based on lastSeen date) 
     BiFunction<RawMetric, Metric, Metric> biFunction = 
      (k, v) -> Metric.builder() 
        .name(k.getMetricName()) 
        .metricType(k.getMetricType()) 
        ... // and more       
        .lastSeen(v.getLastSeen().after(
         metricName.getLastSeen()) ? v.getLastSeen() : 
          metricName.getLastSeen()) 
        .firstSeen(v.getFirstSeen()) 
        .build(); 

     metricsMap.putIfAbsent(rawMetric, metric); 
     metricsMap.computeIfPresent(rawMetric, biFunction); 
    } 

    return ImmutableSet.copyOf(metricsMap.values()); 
} 

@Value 
@Builder 
static class RawMetricName { 
    private String metricName; 
    private String metricType; 
    private String ad; 
    private String project; 
    private String fleet; 
    private String host; 
    private int granularity; 
} 
相關問題