Search code examples
javaooparraylisttypesconstructor

How to set the data type for an ArrayList during the creation of the object in which it is used


I have a Box class object that contains an ArrayList. How can I make it possible to set the data type for this ArrayList when creating the box1 object? For example, only Double from -50.0 to 50.0 for box1 or only Integer from 0 to 10 for box2 or certain Strings for box3.

import java.util.ArrayList;
public class Main {
    public static void main(String[] args) {
        Box box1 = new Box("box1");
        box1.addItem(5);
        box1.addItem(3.14);
        box1.addItem("String");
        System.out.println(box1.getItems());
    }
}

class Box {
    String boxName;
    ArrayList<Object> items = new ArrayList<>();

    Box(String boxName) {
    this.boxName = boxName;
    }

    public void addItem (Object item) {
        this.items.add(item);
    }

    public ArrayList getItems() {
        return this.items;
    }
}

I set the ArrayList to an Object data type, but that's not quite right. It is necessary that each object of the Box class have an ArrayList with an individual data type and a list of valid values.


Solution

  • You can use generics in your code to use specific classes. For example

    class Box<T> {
    
        String boxName;
        List<T> items = new ArrayList<>();
    
        Box(String boxName) {
            this.boxName = boxName;
        }
    
        public void addItem (T item) {
            this.items.add(item);
        }
    
        public List<T> getItems() {
            return this.items;
        }
    }
    

    Additionally, you can add a new Predicate field in a class to use validation. For example

    class Box<T> {
    
        String boxName;
        List<T> items = new ArrayList<>();
        Predicate<T> validator;
    
        Box(String boxName, Predicate<T> validator) {
            this.boxName = boxName;
            this.validator = validator;
        }
    
        public void addItem (T item) {
            if (validator.test(item)) {
                this.items.add(item);
            } else {
                // do nothing, throw exception, depends on your needs
            }
        }
    
        public List<T> getItems() {
            return this.items;
        }
    }
    

    Then you can create your class like this

    var box1 = new Box<Integer>("integerBox", item -> item >= 0 && item <= 10);
    

    Then, when you try to add elements, for the wrong class, you take a compilation error, Java cannot support that purpose, because there is strongly typed language

    box1.addItem(5); 
    box1.addItem(3.14); // compilation error
    box1.addItem("String"); // compilation error