2016-06-14 7 views
1

クラスには、2つの変数productNameproductVersionが含まれています。最新のproductVersionに従って、リスト内の重複項目を置き換える必要があります。2つのカスタムオブジェクトに基づいてリスト内の重複を削除する方法

例:

class ProductDetails { 
    string productName; 
    string productVersion; 
} 
new ProductDetails("ios", "9.1.0") 
new ProductDetails("android", "6.0.1") 
new ProductDetails("android", "5.1.1") 
new ProductDetails("ios", "10.0.0") 

結果:事前に アンドロイド6.0.1 IOS 10.0.0

感謝。

+0

1)製品のバージョンがlongに変換します。 2)productNameでソート、productVersionLongで降順。 3)各商品名の最初の行を保持します。 4)利益! –

+1

これはまったくソートする必要はありません。マップを使用するだけです。最もトリッキーなビットは、バージョン番号を適切に比較します。 –

+0

あなたの入力をいただきありがとうございます。私はリストをソートしたくありません。私はあなたのアプローチを試してみます –

答えて

2

これはあなたのために動作するはずです:

import java.util.ArrayList; 
import java.util.List; 
import java.util.regex.Pattern; 


public class ProductDetails { 

private String productName; 
private String productVersion; 
private List<ProductDetails> productData = null; 

public ProductDetails(String productName,String productVersion){ 
    this.productName = productName; 
    this.productVersion = productVersion; 
    if(productData == null) { 
     productData = new ArrayList<ProductDetails>(); 
     adNewProduct(this); 
    } 
} 

private void adNewProduct(ProductDetails p){ 
    String[] s1 = p.productVersion.split(Pattern.quote(".")); 
    for (ProductDetails dpp: productData) { 
     if (dpp.productName.equals(p.productName)) { 
      int index = productData.indexOf(dpp); 
      String[] s2 = dpp.productVersion.split(Pattern.quote(".")); 
      for(int i = 0; i < s1.length; i++) { 
       int v1 = Integer.valueOf(s1[i]); 
       int v2 = Integer.valueOf(s2[i]); 

       if (v1 > v2) { 
        productData.set(index,p); 
        return; 
       } 
      } 
     } 
    } 
    productData.add(p); 
} 


@Override // you can modify it to how you want 
public String toString(){ 

    String s = ""; 

    for (ProductDetails p: productData){ 
     s += "ProductName: " + p.productName + " ProductVersion: " + p.productVersion + "\n"; 
    } 
    return s; 
} 


//the main method 
public static void main(String[] args) { 
    ProductDetails k = new ProductDetails("ios", "9.1.1"); 
    k.adNewProduct(new ProductDetails("android", "5.1.1")); 
    k.adNewProduct(new ProductDetails("android", "6.0.1")); 
    k.adNewProduct(new ProductDetails("ios", "10.0.0")); 

    System.out.println(k); 

    } 

} 

出力:

商品名:IOS PRODUCTVERSION:10.0.0

商品名:アンドロイドPRODUCTVERSION:6.0.1

+0

なぜネスティングですか? –

+0

@tobias_kは実際には何の違いもありません。この他のクラスで何か他のことをしていた..私はよく編集する必要があると思う。 –

2

これらのオブジェクトをすべてMap<String, ProductDetails>に入れて、最新のバージョンに保つことができます。その後

List<ProductDetails> details = Arrays.asList(
     new ProductDetails("ios", "9.1.0"), 
     new ProductDetails("android", "6.0.1"), 
     new ProductDetails("android", "5.1.1"), 
     new ProductDetails("ios", "10.0.0")); 

// get part of version string 
Function<Integer, Function<ProductDetails, Integer>> version = 
     n -> (pd -> Integer.valueOf(pd.getProductVersion().split("\\.")[n])); 
// chain to comparator 
Comparator<ProductDetails> versionComp = Comparator.comparing(version.apply(0)) 
     .thenComparing(version.apply(1)).thenComparing(version.apply(2)); 

Map<String, ProductDetails> latest = new HashMap<>(); 
for (ProductDetails pd : details) { 
    String name = pd.getProductName(); 
    if (! latest.containsKey(name) || versionComp.compare(latest.get(name), pd) < 0) { 
     latest.put(name, pd); 
    } 
} 

latestは次のとおりです。

{android=Sandbox.ProductDetails(productName=android, productVersion=6.0.1), 
ios=Sandbox.ProductDetails(productName=ios, productVersion=10.0.0)} 

それとも、あなたはCollectors.groupingByを使用して、同じComparatorを使用することができます。

details.stream() 
     .collect(Collectors.groupingBy(ProductDetails::getProductName)) 
     .values().stream().map(list -> Collections.max(list, versionComp)) 
     .forEach(System.out::println); 
関連する問題