Tusker
Tusker

Reputation: 15

Remove duplicate entry using stream

I have a list of item, i want to remove the duplicate values from that.debug variables

This is the list data which I have. Here FIN_NT is duplicated.

private Set<CategoryData> getSetObject(List<List<String>> list,String key, final int codePosition, final int nameposition){
    Function<List<String>,CategoryData> convertListToMap = (l)->{

        CategoryData obj =new CategoryData();
        obj.setCode(l.get(codePosition));
        obj.setName(l.get(nameposition));
        return obj;
    };
    Set<CategoryData> distinct = list.stream().filter(this.contain(key)).map(convertListToMap).distinct().collect(Collectors.toSet());
    
    Set<CategoryData> collect = list.stream().filter(this.contain(key)).map(convertListToMap).collect(Collectors.toSet());
    
    return list.stream().filter(this.contain(key)).map(convertListToMap).collect(Collectors.toSet());
}

This is my code. I need the result in this format.

"finish": [
        {
            "code": "FIN_G",
            "name": "Gloss"
       },
       {
            "code": "FIN_NT",
            "name": "Natural"
       },
       {
            "code": "FIN_SX",
            "name": "Silk"
       }
]

without any duplicate entry.

Upvotes: 0

Views: 209

Answers (2)

Huy Nguyen
Huy Nguyen

Reputation: 2061

Assume you already had List of CategoryData, In case you can't edit/override CategoryData, you should have function to convert CategoryDate to unique key then we can use map with function putIfAbsent to avoid duplication object.

@Test
  public void test() {
    List<CategoryData> list = Arrays.asList(
        new CategoryData("BB","BB"),
        new CategoryData("BB","BB"),
        new CategoryData("CC","CC"),
        new CategoryData("CC","CC"),
        new CategoryData("CC","CC")
        );
    Collection<CategoryData> expected = toUniqueList(list);
    
    Assertions.assertEquals(2, expected.size());
    Assertions.assertEquals("BB_BB", getUniqueKey(expected.get(0)));
    Assertions.assertEquals("CC_CC", getUniqueKey(expected.get(1)));
  } 

  private Collection<CategoryData> toUniqueList(Collection<CategoryData> list) {
    final Map<String, CategoryData> keyValues = new LinkedHashMap<>();
    for (CategoryData cate : list) {
      keyValues.putIfAbsent(getUniqueKey(cate), cate);
    }
    return keyValues.values();
  }

  private String getUniqueKey(CategoryData cate) {
    return String.join("_",cate.getCode(), cate.getName());
  }

Upvotes: 0

Ravindra Ranwala
Ravindra Ranwala

Reputation: 21124

Given that your class has a notion of logical equality over mere object identity, you may override equals and hashcode contract and then create a Set from the collection. Here's the implementation of the contract.

@Override
public int hashCode() {
    int result = codePosition.hashCode();
    result = 31 * result + nameposition.hashCode();
    return result;
}

@Override
public boolean equals(Object obj) {
    if (!(obj instanceof CategoryData))
        return false;
    final CategoryData cd = (CategoryData) obj;
    return cd.codePosition.equals(codePosition) 
        && cd.nameposition.equals(nameposition);
}

Here's the client code:

Set<CategoryData> cdSet = new HashSet<>(cd);

Note that here we use the conversion constructor of the HashSet.

Upvotes: 1

Related Questions