2

I have a DTO that contains a list where I add or I remove some items, in my DAO when I get this list, I want to compare it with the existing one, so all new items that doesn't exist in the old list will be added, and the items in the old list that doesn't exist in the list in the dto will be deleted. for example, this is the items in the list that already exist :

[a,b,c]

And the list in the dto contains this :

[b,d]

So in this case [d] will be inserted and [a] and [c] will be removed.

There is an approach where I can just deleted the old list and then add all the elements in the DTO's list, but I don't want it in this way.

This is what I tried :

public Role updateRoleDTO(final RoleDTO roleDTO) {
    //...
    //... Some code
    //...
    boolean profilExist = false;
    RoleProfil roleProfil = null;

    // Add non existing profils
    for (Profil profil : roleDTO.getProfils()) {
        profilExist = false;
        roleProfil = new RoleProfil();
        for(Profil oldProfil : oldProfilsList){
            if(profil.getId().equals(oldProfil.getId())){
                profilExist = true;
                break;
            }
        }
        if(!profilExist){
            roleProfil.setRoleId(insertedRole);
            roleProfil.setProfilId(profil);
            roleProfilDAO.insert(roleProfil);
        }
    }

    //Remove existing profils that are not in the updated Role
    for(Profil oldProfil : oldProfilsList){
        profilExist = false;
        for (Profil profil : roleDTO.getProfils()) {
            if(oldProfil.getId().equals(profil.getId())){
                profilExist = true;
                break;
            }
        }
        if(!profilExist){
            roleProfilDAO.delete(roleProfilDAO.findRoleProfilByRoleIdAndProfilId(roleDTO.getRoleId(), oldProfil.getId()));
        }
    }

So the first time I will look in the old list if it contains an item in the DTO's list, if it doesn't I will add it. In the second time I will look in the DTO's list if it contains an item in the old list, if it doesn't I wll remove it.

In this approach I have created two loops, each loop contains an intern loop, which looks too long.

Isn't there any other approach I can do it ? or using the Java 8 stream which will make it look better?

7
  • (1) Avoid mutable lists. (2) Then you can just do obj.list = newList Commented Sep 15, 2017 at 16:19
  • 1
    I don't understand your example: "[a,b,c] [b,d] -> [d] will be inserted and [a] will be removed". -- Why isn't c removed? Commented Sep 15, 2017 at 16:23
  • @slim obj.list = newList won't work in my case since obj doesn't know about the list that's why I created the DTO, the items in the list will be inserted in another object. Commented Sep 15, 2017 at 16:24
  • @slim for your second comment, I've updated my question, sorry, it was a mistake Commented Sep 15, 2017 at 16:26
  • I think you can group your DTOs by states first, e.g: [dirty, new, delete]. then you can operate with each other. Commented Sep 15, 2017 at 16:28

2 Answers 2

2

If you can re-model your data structure as a Set (and since you are comparing by id it seems you can do so by just making Profil's hashCode/equals do so), you can easily get it done using Guava's Sets class:

    Set<String> oldSet = Sets.newHashSet("a", "b", "c");
    Set<String> newSet = Sets.newHashSet("b", "d");


    Sets.SetView<String> toRemove = Sets.difference(oldSet, newSet);
    Sets.SetView<String> toInsert = Sets.difference(newSet, oldSet);
    Sets.SetView<String> toUpdate = Sets.intersection(oldSet, newSet);

Or using Java 8's Streams API:

    Set<String> oldSet = new HashSet<>(Arrays.asList("a", "b", "c"));
    Set<String> newSet = new HashSet<>(Arrays.asList("b", "d"));

    Stream<String> toRemove = oldSet.stream().filter(e -> !newSet.contains(e));
    Stream<String> toInsert = newSet.stream().filter(e -> !oldSet.contains(e));
    Stream<String> toUpdate = oldSet.stream().filter(newSet::contains);
Sign up to request clarification or add additional context in comments.

Comments

0
oldProfilsList.addAll(roleDTO.getProfils());
   oldProfilsList.removeIf(op ->!roleDTO.getProfils().contain(oldProfile));
   oldProfilsList =   new ArrayList<Profile>(new HashSet<Profile>(oldProfilsList))  

oldProfilsList will give you the list as required.

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.