[Java] Understand the difference between List and Set

This document is a reprint of the material created for new engineers about 10 years ago. There may be some old-fashioned parts such as API and syntax, but once you learn the idea, I intend to organize the basic parts that can be used for a long time, so I hope that it will be helpful for young engineers now.

Point of understanding

--Understand the difference between List and Set in Java. --List holds duplicate elements. --Set does not hold duplicate elements. ――What are duplicate elements in Java in the first place?

Prerequisites

Use the User class implemented in equals and hashCode. The Object # toString () method is overridden to output the state of the object.

User.java


    class User {

        /** ID */
        private int id;

        /**name*/
        private String name;

        /**
         *It is a constructor.
         * 
         * @param id ID
         * @param name name
         */
        public User(int id, String name) {
            this.id = id;
            this.name = name;
        }

        // (Abbreviation)getter etc.

        /**
         *Returns a hash value of this class.
         * 
         * @return Hash value of this class
         */
        public int hashCode() {
            return this.id * 13;
        }

        /**
         *The instance of this class and the object passed as an argument
         *Returns true if they are equivalent.
         *The object passed as an argument is an instance of User class
         *If the id values are equal, they are considered equivalent.
         *
         * @True if the object passed in the return argument is an instance of the User class and the ids are equal.
         */
        public boolean equals(Object other) {

            if (this == other) { //True if the object passed as an argument is this object itself
                return true;
            }

            if (!(other instanceof User)) { //The object passed as an argument is an object of User class
                return false;               //False if not.
            }

            User otherUser = (User) other;
            if (this.id == otherUser.getId()) { //Compare the ID values, true if they are equal, false if they are not equal.
                return true;
            }
            return false;
        }

        /**
         *A string representation of an instance of this class.
         * 
         * @return A string representation of an instance of this class.
         */
        public String toString() {
            return "User : id = " + id + " name = " + name;
        }
    }

About the difference between List and Set

When adding an element to a class that implements the List interface

--Guarantees the order in which elements are added. In other words, you can get the elements by specifying the index in the order of add (). --Keep duplicate elements. What are overlapping elements in the first place? Will be explained later.

When an element is added to a class that implements the Set interface

--We do not guarantee the order in which elements are added. That is, you cannot get the element by specifying the index. --Does not retain duplicate elements.

Example of adding duplicate elements to List

Judge equivalence by id value (return true if id values are equal in equals method) Add an instance of User class to ArrayList as shown below, and output the added element as a character string as standard output. Then ...

    User user1 = new User(1, "Maekawa");
    User user2 = new User(2, "Suzuki");
    User user3 = new User(3, "Maekawa");
    User user4 = new User(1, "Sato"); //ID is duplicated with user1

    List userList = new ArrayList();
    userList.add(user1);
    userList.add(user2);
    userList.add(user3);
    userList.add(user4);

    for (Iterator userIter = userList.iterator(); userIter.hasNext(); ) {
        User user = (User) userIter.next();
        System.out.println("User in userList: " + user); //Output the contents of the toString method call
    }

The output result is as follows. It is output in the order in which the elements are added, and duplicate elements are retained.

    *****************************************
User in userList: User : id = 1 name =Maekawa
User in userList: User : id = 2 name =Suzuki
User in userList: User : id = 3 name =Maekawa
User in userList: User : id = 1 name =Sato
    *****************************************

Example of adding duplicate elements to Set

Judge equivalence by id value (return true if id values are equal in equals method) Add an instance of User class to HashSet as shown below, and output the added element as a character string as standard. Then ...

    User user1 = new User(1, "Maekawa");
    User user2 = new User(2, "Suzuki");
    User user3 = new User(3, "Maekawa");
    User user4 = new User(1, "Sato"); //ID is duplicated with user1

    Set userSet = new HashSet();
    userSet.add(user1);
    userSet.add(user2);
    userSet.add(user3);
    userSet.add(user4);

    for (Iterator userIter = userSet.iterator(); userIter.hasNext(); ) {
        User user = (User) userIter.next();
        System.out.println("User in userSet: " + user); //Output the contents of the toString method call
    }

The output result is as follows. It is not output (not guaranteed) in the order in which the elements are added, and duplicate elements are not retained.

    *****************************************
User in userSet: User : id = 3 name =Maekawa
User in userSet: User : id = 2 name =Suzuki
User in userSet: User : id = 1 name =Maekawa
    *****************************************

Evolving topics

What is duplication in the first place?

In the first place, "Set" in Java is an abstract expression of the concept of Set in mathematics.

Every element contained in a Set is unique.

That is, elements contained in the same Set cannot be considered the same (equivalent).

Expressing this in Java

It does not have element pairs of e1 and e2, which are e1.equals (e2). Can be expressed as. In a collection such as Set or List in Java, "duplicate elements" are nothing but multiple elements that return true as the return value when comparing two elements (objects) with the equals method.

Since the equals method must be implemented by the programmer (unless you use the default equals method defined in the Object class), the rules for "duplicate" objects in Java vary depending on the business rules of the application and the programmer's implementation. It means that it can be defined by the method.

The elements held by Set differ depending on how the equals method is implemented.

In the previous example, the equivalence of instances of the User class was determined by the value of "ID".

If you implement to judge the equivalence of the instance of User class by the value of "name", how will it behave when the instance of User class is added to Set?

User.java



        //Implementation example of User class that determines equivalence by the value of name
        // (However, for convenience, null is not stored in the value of name.)

        /**
         *Returns a hash value of this class.
         * 
         * @return Hash value of this class
         */
        public int hashCode() {
            return this.name.hashCode();
        }

        /**
         *The instance of this class and the object passed as an argument
         *Returns true if they are equivalent.
         *The object passed as an argument is an instance of User class
         *If the values of name are equal, they are considered equivalent.
         *
         * @True if the object passed in the return argument is an instance of the User class and the names are equal.
         */
        public boolean equals(Object other) {

            if (this == other) { //True if the object passed as an argument is this object itself
                return true;
            }

            if (!(other instanceof User)) { //The object passed as an argument is an object of User class
                return false;               //False if not.
            }

            User otherUser = (User) other;
            if (this.name.equals(otherUser.getName())) { //Compare the values of name, true if equal, false if not equal. Return true;
            }
            return false;
        }

Judge equivalence by the value of name (return true if id values are equal in equals method) Add an instance of User class to HashSet as shown below, and output the added element as a character string as standard. Then ...

    *****************************************
User in userSet: User : id = 1 name =Sato
User in userSet: User : id = 2 name =Suzuki
User in userSet: User : id = 1 name =Maekawa
    *****************************************

further

--What happens if you don't implement the equals and hashCode methods? --What happens if you implement the equals method and not the hashCode method?

Please check

Recommended Posts

[Java] Understand the difference between List and Set
Understand the difference between each_with_index and each.with_index
[iOS] Understand the difference between frame and bounds
Understand the difference between abstract classes and interfaces!
[Java] Difference between == and equals
Difference between List and ArrayList
Understand the difference between int and Integer and BigInteger in java and float and double
[JAVA] What is the difference between interface and abstract? ?? ??
What is the difference between Java EE and Jakarta EE?
Find the difference between List types
[Java] Difference between Hashmap and HashTable
[JAVA] Difference between abstract and interface
[Java] Difference between array and ArrayList
[Java] Difference between Closeable and AutoCloseable
[Java] Difference between StringBuffer and StringBuilder
[Java] Difference between length, length () and size ()
Difference between Java and JavaScript (how to find the average)
[Java] Check the difference between orElse and orElseGet with IntStream
Difference between final and Immutable in Java
[For beginners] Difference between Java and Kotlin
[Java 7] Divide the Java list and execute the process
About the difference between irb and pry
Arrylist and linked list difference in java
[Java] Difference between Intstream range and rangeClosed
Difference between int and Integer in Java
[Java] What is the difference between form, entity and dto? [Bean]
Easy to understand the difference between Ruby instance method and class method.
[Rails / ActiveRecord] About the difference between create and create!
Difference between next () and nextLine () in Java Scanner
What is the difference between SimpleDateFormat and DateTimeFormatter? ??
Summarize the differences between C # and Java writing
Difference between vh and%
[Java] Difference between "final variable" and "immutable object"
Difference between i ++ and ++ i
[Ruby] I thought about the difference between each_with_index and each.with_index
[Rails] I learned about the difference between resources and resources
What is the difference between a class and a struct? ?? ??
[Java] Sort the list using streams and lambda expressions
What is the difference between System Spec and Feature Spec?
About the difference between classes and instances in Ruby
[Java] Difference between static final and final in member variables
[Rails] What is the difference between redirect and render?
Compare the difference between dockerfile before and after docker-slim
Java classes and instances to understand in the figure
What is the difference between skip and pending? [RSpec]
[Rails] I investigated the difference between redirect_to and render.
[Swift] UITextField taught me the difference between nil and ""
[Java beginner] Difference between length and length () ~ I don't know ~
Difference between product and variant
Difference between redirect_to and render
Rails: Difference between resources and resources
Difference between puts and print
Difference between redirect_to and render
Difference between CUI and GUI
Difference between variables and instance variables
Difference between mockito-core and mockito-all
Difference between class and instance
Difference between bundle and bundle install
Difference between ArrayList and LinkedList
Difference between render and redirect_to
java Generics T and? Difference