user1502377
user1502377

Reputation: 71

Simultaneously Iterate over multiple arrayLists in Java..Most efficiently

I am writing an API, which creates a list of User objects and then makes a call to a 3rd party webservice with that list. The 3rd party webservice then responds back with a list of UserDetails objects containing the details of the users. For ex:

Class User{
String id;
String name;
}

A list is constructed with the above User objects and then passed over to the 3rd party webservice.

List<User> users = new ArrayList <User>();

The 3rd party webservice then responds back with a list of UserDetails Objects.

Class UserDetails {
    String id;
    String email;
    String accountNumber;
    ...
    ...
    }


List<UserDetails> userDetails = new ArrayList <UserDetails>();

Now, to construct the response of my API, I construct a List of UserResponse objects which contains a mix of fields in User and UserDetails objects.

Class UserResponse{
String id;
String name;
String email;
String accountNumber;
....
...

}

To Construct this list of UserResponse objects, I have to iterate over user List and UserDetails List and then check if id's match and then construct the UserRepsonse Object and then add them to a list. The code is as below.

List <UserResponse> userResponseList = new ArrayList<UserResponse>();
for(User user : userRequest){
 for(UserDetails userDetail: userDetails){

if(user.getid().equalsIgnoreCase(userDetail.getId())){
    UserResponse userReponse = new UserResponse ();
    userReponse.setId(user.getId());
    userReponse.setName(user.getName());
    userReponse.setEmail(userDetail.getEmail());
    userReponse.setAccountNumber(userDetail.getAccountDetail());

    userResponseList.add(userReponse);

    }
 }
}

And then return the userResponseList.

The above code works. But iterating over 2 lists is what is scaring me. My API can have about 200 users in 1 request. So I send a list of 200 user objects to 3rd party service and then the 3rd party webservice responds back with a list of 200 userDetails objects.

This means I will be iterating 200*200 items in the double iterator.

Is there an better and more efficient way to perform this logic instead of iterating this many times ?

Advance Thanks..

Upvotes: 0

Views: 1480

Answers (3)

Aliaksei Yatsau
Aliaksei Yatsau

Reputation: 749

Use java.util.Collections class and it's static methods. Also define size of your ArrayList if you can or use LinkedList if you don't have problem with memory and you don't bother about getting element x for example userResponseList.get(5).

List <UserResponse> userResponseList = new ArrayList<UserResponse>(userRequest.size());
userDetails.removeAll(Collections.singletonList(null)); // removes all nulls.
Comparator<String> comparator = new Comparator<String>(){
@Override
public int compare(String o1, String o2) {return o1.compare.o2;}
}

Collections.sort(userDetails, comparator);
UserDetails ud = new UserDetails();
for(User user : userRequest){
    ud.setId(user.getId());
    int index = Collections.binarySearch(userDetails, ud, comparator);
    if(index >= 0){    
       UserResponse userReponse = new UserResponse ();
       userReponse.setId(user.getId());
       userReponse.setName(user.getName());
       userReponse.setEmail(userDetail.getEmail());
       userReponse.setAccountNumber(userDetail.getAccountDetail());
       userResponseList.add(userReponse);
    }
}

Upvotes: 0

AndreiV
AndreiV

Reputation: 99

If you want to keep your data structures, you could sort the two arrays first by id (using Arrays.sort which has a worst case complexity of O(nlogn), and then search only once as pointed out by Ben Knoble.

This will reduce your complexity from n^2 to n log n , specifically in your case to 2 * 200 * log(200) + 2 * 200 operations = 1320 ops down from 40000+.

Upvotes: 0

Slimu
Slimu

Reputation: 2371

Since you use the id field as the common identifier, for both objects, why don't you try to make a map with the UserDetails grouped by id. After that you iterate the Users list and use the map.get(id) to retrieve for each User it's details and so you can build the desired list of objects based on those two type of objects.

Upvotes: 1

Related Questions