1

I have ProductDetail class which contains two variables productName and productVersion. I need to replace duplicate items in the list according to the latest productVersion.

Example:

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")

Result: android 6.0.1 ios 10.0.0

Thanks in advance.

4
  • 1) Convert product version to a long. 2) Sort by productName, productVersionLong descending. 3) Keep first row of each productName. 4) Profit!! Commented Jun 14, 2016 at 13:25
  • 1
    This does not need sorting at all. Just use a Map. The most tricky bit will be properly comparing the version numbers. Commented Jun 14, 2016 at 13:32
  • thank you for your input guys. I do not want to sort a list. I will try your approach Gilbert Le Blanc Commented Jun 14, 2016 at 13:46
  • @RIACreate will this help, i hope this is the right answer you are looking for link Commented Jun 14, 2016 at 16:43

2 Answers 2

2

This should work out for you:

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);

    }

}

Output:

ProductName: ios ProductVersion: 10.0.0

ProductName: android ProductVersion: 6.0.1

Sign up to request clarification or add additional context in comments.

1 Comment

@tobias_k doesn't really make any difference. was doing something else in this other class.. i think i have to edit well.
2

You can put all those objects into a Map<String, ProductDetails> and keep the one with the latest version.

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);
    }
}

Afterwards, latest is:

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

Or, you can use Collectors.groupingBy and then use the same Comparator:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.