开发者

Why does some libs define their own collections?

开发者_StackOverflow社区For example, in Jsoup, they defined a class Elements to collect Element(s).

It's common to define a class A and As which contains a lot of A(s). But why? Why don't we just use ArrayList or something?


The Elements class in JSoup has many specific methods to its function e.g.

toggleClass(String className) 
html()

Which wouldn't be available on ArrayList. I guess ArrayList could have been extended, but the author of Elements has gone for composition. Elements HAS-A ArrayList instance which it keeps private. Elements exposes methods of the List interface, bespoke methods and others.

But Elements is backed by an ArrayList - this way the author can also decorate the methods of ArrayList he chooses to make public via his own Class. This is an extract from the source code:

  private List<Element> contents;

    public Elements() {
        contents = new ArrayList<Element>();
    }

BTW: You used to see wrappers pre Java 5 to give type safety to Java Collections, but since Java 5 Generics have stopped a lot of this.


For this special example looking at the API shows you that in addition to the plain collection methods, Elements provides related to HTML processing. Hence the implementation of a custom collection. Beside you'll notice that Elements implements Iterable, Collection and List.


Another reason is to introduce domain specific entities. That means for example, yes, Elements is just a List, could be implemented as ArrayList. So thru all the code you see ArrayList that contains Element. When reading code that is not that easy to read. But if i see a type Elements i know the program talks about a collection of Element, because JSoup's domain are HTML documents made of elements ...


There are basically three reasons to create a custom container:

  • The available containers lack functionality that is required.
  • The performance of available containers do not match the needs.
  • The code should minimize external dependencies.

I do not know which one (if any) applies to your example. I would not call a dependency on ArrayList as external, but in e.g. C++ it might be valid, not to rely on containers from the C++ Standard Library for that reason.


I assume it's beacause of the code being written for java 1.4 and below: At this time there was no opportunity for using Generics like ArrayList<String>for type-safe collections.


It is most likely that the List interface (or any other collection interface) does not suit their needs. The authors may want to have specialized methods that do things that a collection interface doesn't allow.

If you look close enough, you'll see that Elements infact implements List<Element>.


Well, standard collections do the trick for a lot of user cases, but sometimes we need advanced features, different performance characteristics and such. Data Structures are a important subject in Computer Science, and people are getting their PhD Thesis out of it all the time. Even for common users cases, there are a lot of libraries out there trying to improve over standard collections. Notable examples are Google Guava and Apache Collections


There is a design pattern, Composite. It allows to build an structure that may contain elements and collections of elements. The main idea is to allow to the client of the library to treat the entire collection as a simple list of elements, without knowledge about it's structure.


Just an answer which is a bit different from the others:

For some libraries like KryoNet, it is necessary for tight optimisation (i.e., disallow null keys and values, lock keys and values to a particular type) that a particular usage of a collection class can be identified. The best way to do this is via extension, since this means that a Class->ClassOptimisation map, as an example, works fine. Otherwise, you'd get a load of class instances being optimised in peculiar ways that you don't want.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜