Это решение, которое я реализовал для собственной проблемы, может быть, оно может быть полезно кому-то еще.
Я создал объект LazyList
, для которого требуется ListInitializer
, при первой операции LazyList
вызовет ListInitializer
, который вернет List
, LazyList
затем делегирует все операции List
, возвращенному из ListInitializer
.В моем конкретном случае ListInitializer
преобразует и возвращает преобразованный List
.Таким образом, мой List
не будет преобразован, если LazyList
никогда не будет использоваться.
public class LazyList<T> implements List<T> {
private final ListInitializerSingleton<T> singleton;
public LazyList(ListInitializer<T> initializer) {
this.singleton = new ListInitializerSingleton<>(initializer);
}
@Override
public int size() {
return singleton.list().size();
}
@Override
public boolean isEmpty() {
return singleton.list().isEmpty();
}
@Override
public boolean contains(Object o) {
return singleton.list().contains(o);
}
@NotNull
@Override
public Iterator<T> iterator() {
return singleton.list().iterator();
}
@NotNull
@Override
public Object[] toArray() {
return singleton.list().toArray();
}
@NotNull
@Override
public <T1> T1[] toArray(@NotNull T1[] a) {
return singleton.list().toArray(a);
}
@Override
public boolean add(T t) {
return singleton.list().add(t);
}
@Override
public boolean remove(Object o) {
return singleton.list().remove(o);
}
@Override
public boolean containsAll(@NotNull Collection<?> c) {
return singleton.list().containsAll(c);
}
@Override
public boolean addAll(@NotNull Collection<? extends T> c) {
return singleton.list().addAll(c);
}
@Override
public boolean addAll(int index, @NotNull Collection<? extends T> c) {
return singleton.list().addAll(index, c);
}
@Override
public boolean removeAll(@NotNull Collection<?> c) {
return singleton.list().removeAll(c);
}
@Override
public boolean retainAll(@NotNull Collection<?> c) {
return singleton.list().retainAll(c);
}
@Override
public void clear() {
singleton.list().clear();
}
@Override
public T get(int index) {
return singleton.list().get(index);
}
@Override
public T set(int index, T element) {
return singleton.list().set(index, element);
}
@Override
public void add(int index, T element) {
singleton.list().add(index, element);
}
@Override
public T remove(int index) {
return singleton.list().remove(index);
}
@Override
public int indexOf(Object o) {
return singleton.list().indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
return singleton.list().lastIndexOf(o);
}
@NotNull
@Override
public ListIterator<T> listIterator() {
return singleton.list().listIterator();
}
@NotNull
@Override
public ListIterator<T> listIterator(int index) {
return singleton.list().listIterator(index);
}
@NotNull
@Override
public List<T> subList(int fromIndex, int toIndex) {
return singleton.list().subList(fromIndex, toIndex);
}
@FunctionalInterface
public interface ListInitializer<T> {
List<T> initialize();
}
private class ListInitializerSingleton<T> {
private final ListInitializer<T> initializer;
private List<T> list;
ListInitializerSingleton(ListInitializer<T> initializer) {
this.initializer = initializer;
}
List<T> list() {
if (list == null) {
list = initializer.initialize();
}
return list;
}
}
}
Использование:
DeckModel convert(Deck deck) {
DeckModel model = new DeckModel();
model.setName(deck.getName());
LazyList<CardModel> cards = new LazyList<>(() -> {
deck.getCards().stream()
.map(card -> convert(card))
.collect(Collectors.toList());
})
model.setCards(cards);
return model;
}
CardModel convert(Card card) {
CardModel model = new CardModel();
model.setName(card.getName());
LazyList<DeckModel> decks = new LazyList<>(() -> {
card.getDecks().stream()
.map(deck -> convert(deck))
.collect(Collectors.toList());
})
model.setDecks(deks);
return model;
}