I have an Item
which has a method List<Item> getChildren()
(which returns an immutable list) and for each of the items I have, I need to create a list of the item followed by its children.
What's the quickest way to "cons" (in the Lisp/Scheme sense) my item to create a new immutable list? I can certainly do the following, but it seems wrong/wasteful:
public List<Item> getItemAndItsChildren(Item item)
{
if (item.getChildren.isEmpty())
return Collections.singletonList(item);
else
{
// would rather just "return cons(item, item.getChildren())"
// than do the following -- which, although straightforward,
// seems wrong/wasteful.
List<Item> items = new ArrayList<Item>();
items.add(item);
items.addAll(item.getChildren());
return Collections.unmodifiableList(items);
}
}
There are two methods to add elements to the list. add(E e): appends the element at the end of the list. Since List supports Generics, the type of elements that can be added is determined when the list is created. add(int index, E element): inserts the element at the given index.
contains() method can be used to check if a Java ArrayList contains a given item or not. This method has a single parameter i.e. the item whose presence in the ArrayList is tested. Also it returns true if the item is present in the ArrayList and false if the item is not present.
The Java String contains() method is used to check whether the specific set of characters are part of the given string or not. It returns a boolean value true if the specified characters are substring of a given string and returns false otherwise.
I'd change my requirements. In most cases, you don't need a List
in your interface, an Iterable
will do nicely. Here's the method:
public Iterable<Item> getItemWithChildren(Item item) {
return Iterables.unmodifiableIterable(
Iterables.concat(
Collections.singleton(item),
item.getChildren()
)
);
}
and here's the shortened version (with static imports):
return unmodifiableIterable(concat(singleton(item), item.getChildren()));
The ability to create a new immutable list by concatenating a head element to a tail that may be shared between other lists requires a singly-linked list implementation. Java doesn't provide anything like this out of the box, so your ArrayList
solution is as good as anything.
It's also going to be relatively efficient, assuming that these lists are short-lived and you don't have tens of thousands of element in the list. If you do, and if this operation is taking a significant portion of your execution time, then implmenting your own single-linked list might be worthwhile.
My one change to improve your existing efficiency: construct the new list with a capacity (1 + size of old list).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With