I have a class (A.java) that contains two private fields of type ArrayList and HashMap.
I also have another class (B.java) that should have access to their data. I could make two getters, but I don't want to return my collections as is. Class B.java should only have access to data, not to add(), isEmpty(), containsKey() etc.
Can I return my collections in such way, so I could somehow use it with foreach in class B somehow but without giving the possibility to modify them?
Asked
Active
Viewed 289 times
0

John
- 467
- 1
- 6
- 23
-
2Just design your getter to return either a copy of the collections or an unmodifiable collection (easy to do with Collections.unmodifiableList method) then you don't have to worry about someone from outside adding something to the list. But what would be so horrible about beeing able to call isEmpty or containsKey? – OH GOD SPIDERS May 17 '18 at 13:27
-
See https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#unmodifiableList(java.util.List) and the related methofd Collections.unmodifiableMap(java.util.Map). – Michael Peacock May 17 '18 at 13:30
-
The `unmodifiable...` methods are the standard way to go. There are several related questions, by the way, e.g. the more general one at https://stackoverflow.com/questions/23607881/returning-a-private-collection-using-a-getter-method-in-java , or, elaborating the option of returning a `Stream`, this one: https://stackoverflow.com/questions/24676877/should-i-return-a-collection-or-a-stream – Marco13 May 17 '18 at 13:39
2 Answers
3
Don't return a collection, return a Stream
. That way it is easy for the user to know that they are getting a stream of objects, not a collection. And it's easy to change the implementation of the collection without changing the way it's used. It's trivial for the user to filter, map, reduce collect etc.
So:
class A {
private List<C> cs = new ArrayList<>();
public Stream<C> getCs() {
return cs.stream();
}
}
class B {
public void processCs(A a) {
a.getCs().filter(C::hasFooness).forEach(...);
}
}

sprinter
- 27,148
- 6
- 47
- 78
2
Create a getter method that returns a "Collections.unmodifiableList()" like this:
List<String> strings = new ArrayList<String>();
List<String> unmodifiable = Collections.unmodifiableList(strings);
unmodifiable.add("New string"); // will fail at runtime
strings.add("Aha!"); // will succeed
System.out.println(unmodifiable);

Diego Torres Fuerte
- 106
- 7
-
I hoped there is more ellegant solution. But ok. I'll just "return Collections.unmodifiableList(myList);". – John May 17 '18 at 13:33