Performance and Memory allocation comparison between List and Set

JavaListCollectionsSet

Java Problem Overview


I want to know the comparison between List and Set in terms of performance,memory allocation and usability.

If i don't have any requirement of keeping the uniqueness in the list of objects, neither required the insertion order to be maintained, Can I use ArrayList and SortedSet/HashSet interchangeably? Will it be good to directly use Collections class instead of even list/set?

P.S. I also don't have any need for list or set specific functions provided by java. I am using List/Set instead of Array only because they can dynamically grow without extra programming efforts.

Java Solutions


Solution 1 - Java

HashSet consumes about 5.5 times more memory than ArrayList for the same number of elements (although they're both still linear), and has significantly slower iteration (albeit with the same asymptotics); a quick Google search suggests a 2-3x slowdown for HashSet iteration versus ArrayList.

If you don't care about uniqueness or the performance of contains, then use ArrayList.

Solution 2 - Java

If you don't care about the ordering, and don't delete elements, then it really boils down to whether you need to find elements in this data structure, and how fast you need those lookups to be.

Finding an element by value in a HashSet is O(1). In an ArrayList, it's O(n).

If you are only using the container to store a bunch of unique objects, and iterate over them at the end (in any order), then arguably ArrayList is a better choice since it's simpler and more economical.

Solution 3 - Java

If you plan only to add elements and later iterate over them, your best bet is ArrayList as it's closest to the arrays you are replacing. It's more memory efficient than LinkedList or any Set implementation, has fast insertion, iteration, and random access.

Solution 4 - Java

If you will compare, searching between List and Set, Set will be better because of the underline Hashing algorithm.

In the case of a list, in worst case scenario, contains will search till the end. In case of Set, because of hashing and bucket, it will search only subset.

Sample use case: Add 1 to 100_000 integer to ArrayList and HashSet. Search each integer in ArrayList and HashSet.

Set will take 9 milliseconds where as List will take 16232 seconds.

private static void compareSetvsList(){
	List<Integer> list = new ArrayList<>() ;
	Set<Integer> set = new HashSet<>() ;

	System.out.println("Setting values in list and set .... ");
	int counter = 100_000  ;

	for(int i =0 ; i< counter ; i++){    		 
		list.add(i);
		set.add(i);
	}

	System.out.println("Checking time .... ");
	long l1 = System.currentTimeMillis();
	for(int i =0 ; i< counter ; i++) list.contains(i);

	long l2 = System.currentTimeMillis();
	System.out.println(" time taken for list : "+ (l2-l1));

	for(int i =0 ; i< counter ; i++)set.contains(i);

	long l3 = System.currentTimeMillis();
	System.out.println(" time taken for set : "+ (l3-l2));

	//    	for 10000   time taken for list : 123     	 time taken for set : 4
	//      for 100000  time taken for list : 16232     	 time taken for set : 9
	//      for 1000000 time taken for list : hung     	 time taken for set : 26

}

Solution 5 - Java

If you don't have the requirement to have unique elements in collection simply use ArrayList unless you have very specific needs.

If you have the requirement to have only unique elemets in collection, then use HashSet unless you have very specific needs.

Concerning SortedSet (and it's implementor TreeSet), as per JavaDoc:

> A Set that further provides a total ordering on its elements. The elements are ordered using their natural ordering, or by a Comparator typically provided at sorted set creation time.

Meaning it's targeted at quite specific use cases, when elements should be always ordered in a set, which is not needed usually.

Solution 6 - Java

Use HashSet if you need to use .contains(T) frequently.

Example:

private static final HashSet<String> KEYWORDS = Stream.of(new String[]{"if", "do", "for", "try", "while", "break", "return"}).collect(Collectors.toCollection(HashSet::new));

public boolean isKeyword(String str) {
     return KEYWORDS.contains(str);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPriyank DoshiView Question on Stackoverflow
Solution 1 - JavaLouis WassermanView Answer on Stackoverflow
Solution 2 - JavaNPEView Answer on Stackoverflow
Solution 3 - JavaMarko TopolnikView Answer on Stackoverflow
Solution 4 - JavaManojView Answer on Stackoverflow
Solution 5 - JavaYuriy NakonechnyyView Answer on Stackoverflow
Solution 6 - JavaDave_czView Answer on Stackoverflow