Коллекции Java-интерфейсов - PullRequest
2 голосов
/ 14 октября 2011

Я пишу небольшой API для работы с объектами, которые имеют определенные «черты». В этом случае у них всех есть интервал времени и пара других бит данных, поэтому я пишу интерфейс TimeInterval с некоторыми геттерами и сеттера.

Теперь большинство из этих методов API имеют дело с множеством или списком объектов. Внутренне эти методы используют Java Collections Framework (в частности, HashMap / TreeMap). Итак, эти методы API похожи на:

getSomeDataAboutIntervals(List<TimeInterval> intervalObjects);

Пара вопросов:

а) Должно ли это быть List<? extends TimeInterval> intervalObjects вместо этого?

Это в основном вопрос стиля? Единственный недостаток использования строго интерфейса, который я вижу, заключается в том, что вам нужно создать свой список как List<TimeInterval>, а не List<ObjectThatImplementsTimeInterval>. Это означает потенциальную необходимость скопировать List<Object..> в List<TimeInterval>, чтобы передать его API.

Есть ли другие плюсы и минусы для любого подхода?

б) И еще один тупой вопрос :) Структура коллекций гарантирует, что я всегда получаю один и тот же экземпляр, который я вставил, коллекции действительно являются коллекцией ссылок, верно?

Ответы [ 5 ]

2 голосов
/ 14 октября 2011

1) Да.

Параметры метода должны быть максимально общими. List<? extends A> является более общим, чем List<A>, и может использоваться, когда вам не нужно добавлять что-либо в список. Если бы вы только добавляли в список (а не читали из него), самая общая подпись, вероятно, была бы List<? super A>

И наоборот, возвращаемые методы должны быть как можно более конкретными. Вы редко хотите никогда не возвращать универсальный шаблон из метода.

Иногда это может привести к общим сигнатурам:

<T extends MyObject> List<T> filterMyObjects(List<T>)

Эта подпись является как можно более конкретной и общей

2) Да, за исключением, возможно, некоторых редких очень специфических случаев (я думаю о BitSet, хотя технически это не Collection).

1 голос
/ 14 октября 2011

1) Я бы порекомендовал?расширяет TimeInterval.Из-за полиморфизма Java это может не иметь никакого значения, но это более надежный и лучший стиль

1 голос
/ 14 октября 2011

Если вы объявите свой список как List<? extends A>, то вы можете передать любой объект, статический тип которого равен List<X>, где X extends A, если A - это класс, или X implements A id A - это класс.интерфейс.Но вы не сможете передать ему List или List<Object> (если A не Object) без принудительного приведения его.

Однако, если вы объявите параметркак List<A>, вы сможете только передавать списки, статический тип которых строго эквивалентен List<A>, например, не List<X>.И под «вы не можете поступить иначе», я действительно имею в виду «если вы не заставите компилятор закрыть и принять его», что, я считаю, не следует делать, если вы не имеете дело с устаревшим кодом.

Коллекциидействительно коллекции ссылок.Абстракция на самом деле заключается в том, что все, что вы можете поместить в переменную, является ссылкой на что-то, если только эта переменная не имеет примитивного типа.

0 голосов
/ 14 октября 2011

Должно ли это быть вместо List ListObjects?

Вы делаете это только в том случае, если хотите передать List<TimeIntervalSubclass>.Обратите внимание, что вы можете поместить экземпляры подклассов TimeInterval в List<TimeInterval>.Помните, что тип списка отличается от типов в списке .

Если вы делаете List<? extends A> myList - это влияет только на то, что вы можете присвоить myList, что отличается от того, что в myList.

И еще один тупой вопрос :) Инфраструктура коллекций гарантирует, что я всегда получаю один и тот же экземпляр, который я вставил, коллекции действительно являются коллекцией ссылок, верно?

Когда вы создаете коллекцию Map myMap = new HashMap(), myMap является ссылкой на базовую коллекцию.Аналогично, когда вы помещаете что-то в коллекцию, вы помещаете ссылку на базовый объект в коллекцию.

0 голосов
/ 14 октября 2011

a) Нет. List<? extends TimeInterval> будет принимать только те интерфейсы, которые расширяют интерфейс TimeInterval. Ваше утверждение, что «вам нужно создать свой список как List<TimeInterval>, неверно, если я не понимаю вашу точку зрения. Вот пример:

List<List> mylist=  new ArrayList<List>();
mylist.add(new ArrayList());

б) Да.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...