1

The codes is comparing 2 list of codes.First list is got from api call and second from database.I am using 2 loops to iterate over the list and compare them ,and add the common to a new list.The first list contains around 800 data and second list(from db) contains 150 data.Is there any way to improve the performance of this code.I am not allowed to make any changes in AllowedCodes Class.Does using nested loops affect performance with the given amount of data?

public class AllowedCodes { private String codeValue=""; public String getCodeValue() { return codeValue; } public void setCodeValue(String codeValue) { this.codeValue = codeValue; } } public class CheckCodes { public static void main(String[] args) { List<AllowedCodes> old_codes_list=getListOfOldCodes(); List<AllowedCodes> new_codes_list=new ArrayList<>(); String sql = "This query gets the codes from database"; PreparedStatement statement = connection.prepareStatement(sql); ResultSet result = statement.executeQuery(); while(result.next()) { for(AllowedCodes a:old_codes){ if(a.getCodeValue().equalsIgnoreCase(result.getCodeValue())){ new_codes_list.add(a); } } } } } 
9
  • 1
    Yes. Use a HashSet instead of a list for old_codes_list. (Store and compare codes as lower case to ignore the original casing.) Commented Sep 8, 2020 at 21:00
  • It has to be an ArrayList.Thats what the response i get from api call.And there are no duplicates.Is there any way to decrease time complexity? Commented Sep 8, 2020 at 21:01
  • 1
    "Thats what the response i get from api call." copy it into a HashSet. Or some other data structure, like a Trie. Commented Sep 8, 2020 at 21:01
  • 1
    The copying will cost you some, but you can then replace the linear for loop with a set.contains(...) which runs in constant time (amortized). (You'll do 1 linear operation, instead of hundreds.) Commented Sep 8, 2020 at 21:06
  • 1
    @LoneWolf: There are plenty of articles on how HashMap works. It involves grouping items based on a modulus of their getHashCode() value, so it doesn't have to call equals() on every item in the collection. You probably don't need to worry about the implementation details, though, so much as the fact that contains() is a O(1) operation, so creating a Map and checking all the items becomes a O(n)-complexity operation instead of O(n²). Commented Sep 8, 2020 at 21:15

1 Answer 1

1

Copy the list into a HashMap, grouping AllowedCodes that have the same code value when lowercased:

Map<String, List<AllowedCodes>> map = old_codes.stream().collect(groupingBy(a -> a.getCodeValue().toLowerCase())); 

Then, in your while loop:

while(result.next()) { String resultCodeValue = result.getCodeValue().toLowerCase(); for (AllowedCodes a : map.getOrDefault(resultCodeValue, Collections.emptyList())) { new_codes_list.add(a); } } 
Sign up to request clarification or add additional context in comments.

5 Comments

I will try using steam api ,never used it before.Thanks Andy
You could use the stream api to avoid the while loop entirely, right? Just have a one-liner that creates the list after a .filter(...contains(...))?
will it work with a resultSet? Please provide a code.I will try using it.I am new to stream api.
@LoneWolf this uses the code your question shows: "result.getCodeValue()".
Yes @Andy , your code helps a lot.I was referring to StriplingWarrior ,whether the code he says works.