"Program to an interface, not an implementation" is one of the most repeated design principles in Java. It means you should declare variables, parameters, and return types using interface types rather than concrete classes.
// Tied to a specific class:
ArrayList<String> names = new ArrayList<>();
// Programmed to an interface:
List<String> names = new ArrayList<>();
Why does this matter? If you later switch from ArrayList to LinkedList, the second version requires changing only line. The first version forces you to find and update every method signature, return type, and variable that mentions ArrayList. In large codebases, that kind of change cascades through dozens of files.