Эффективно Typecast элементы вектора в Java - PullRequest
4 голосов
/ 04 августа 2010

Есть ли более эффективный способ (предпочтительно O (1), а не O (n), но , по крайней мере, быстрее набрать ), чтобы типизировать элементы вектора, чем этот?

public Vector<String> typecastVector(Vector<Object> objects){
    Vector<String> strings = new Vector<String>();
    for(Object o : objects)
        strings.add((String) o);
    return strings;
}

Примечание

Для любого, кто сталкивается с очевидной необходимостью типизировать Vector или другой класс Generic: как указывает принятый ответчик, это, вероятно, запах кода ивам, вероятно, понадобится рефакторинг кода в вашей иерархии классов.

В частности , если вы этого еще не сделали, вам следует подумать о создании классов, которые используют Vector или другой класс Generic сами используют Generics .Когда я сделал это в своем собственном коде, я полностью исключил необходимость функции в моем коде, которая была бы аналогична вышеуказанной функции.

Если вы никогда не использовали Generics в своем собственном коде, проверьте ссылку «Generics» выше.Вы можете быть удивлены (как и я), обнаружив, что они могут быть использованы для реализации именно той функциональности, которая, как вы думали, вам нужна от Vector typecast.

Ответы [ 7 ]

6 голосов
/ 04 августа 2010

Если единственное, что вы хотите сделать, это привести из вектора к вектору , то вы можете это сделать.Вы должны быть уверены, что каждый объект в вашем векторе является строкой!

Очевидно, это не сработает:

    Vector<Object> objectVector = new Vector<Object>();
    Vector<String> stringVector = (Vector<String>)objectVector;

Но вы можете сделать это:

    Vector<Object> objectVector = new Vector<Object>();
    Vector typelessVector = objectVector;
    Vector<String> stringVector = (Vector<String>)typelessVector;

Вы получите несколько предупреждений, но код должен работать нормально.

Как упоминалось ранее, это похоже на запах кода.

3 голосов
/ 04 августа 2010

Если вы определенно пытаетесь создать новую независимую коллекцию, которая содержит копию N ссылок, трудно понять, как это может быть O (1) без поддержки копирования при записи.

Нашли ли вы, что на самом деле является узким местом в производительности вашего кода? И есть ли причина, по которой вы используете Vector вместо ArrayList?

2 голосов
/ 04 августа 2010

Если вы немного подумаете об этом, вы поймете, что, если вам придется конвертировать каждый элемент массива, вы всегда будете иметь O (n).

Поскольку компилятор не может знать заранее, все ли объекты в векторе объектов являются строками, вы не можете привести вектор напрямую, а только элемент за элементом.

1 голос
/ 04 августа 2010

Вы можете написать класс-оболочку, который выполняет приведение по требованию при получении элемента. Это может иметь смысл, если список большой и вы хотите отложить снижение производительности до фактического использования элемента. С другой стороны, он будет приводить каждый элемент каждый раз, когда к нему обращаются, поэтому, если вы будете обращаться к элементам вектора несколько раз, это может быть плохой идеей.

В существующем коде вы также можете сконструировать вектор с правильной емкостью:

Vector<String> strings = new Vector<String>(objects.size());

Это может повысить эффективность, так как ему не придется многократно выделять больше памяти, если ваш список большой.

1 голос
/ 04 августа 2010

Это действительно лучший способ сделать это.

Чтобы привести n элементов к String, вам необходимо «обработать» все n элементов. Это означает, что нижняя граница времени работы должна быть O(n).

Что касается набора текста, вы уже сделали всю работу. Просто поместите этот метод в служебный класс и вызывайте его, когда вам нужно.

0 голосов
/ 04 августа 2010

Вы пытаетесь использовать функцию времени выполнения, чтобы удалить функцию времени компиляции; дженерики все равно раздеваются.

Как уже отмечали другие, гораздо лучше найти источник этого вектора и определить его как вектор . Таким образом, вы будете использовать предупреждения вашего компилятора о размещении «неправильного» объекта в векторе вместо того, чтобы узнавать, было ли там что-то плохое во время выполнения программы.

Одна из проблем, с которой сталкивается этот код, заключается в том, что при извлечении вектора из вектора код может завершиться ошибкой. С точки зрения отладки, сбой на этапе преобразования не очень полезен. Было бы гораздо лучше потерпеть неудачу на этапе вставки, потому что тогда у вас была бы возможность немедленно отреагировать на проблему, вместо того, чтобы позволить ей скрываться, чтобы другие части кода могли ее обнаружить.

Я понимаю, что вы обеспокоены скоростью набора текста; но это странная метрика. Всегда быстрее не преобразовывать что-либо, потому что оно набрано правильно в первую очередь; и скорость набора текста не должна быть оптимизирована, потому что обычно это делается за счет читабельности, правильной структуры кода, разумного дизайна и т. д. Если вам приходится печатать что-то несколько раз, возможно, пришло время создать абстрактный базовый класс или используйте другие средства, чтобы разрешить написание одной копии необходимого кода.

0 голосов
/ 04 августа 2010

Во-первых, вы должны избегать использования вектора , если это «действительно» вектор . Объект является ошибкой в ​​Java.

Вы получите предупреждение компилятора, и на то есть веская причина, но вы можете сначала пройти маршрут приведения к вектору, а затем к вектору . Это O (1), и довольно глупо, так как позже вы можете получить строку кода вроде String s = vector.get (1); выдача ClassCastException, если вы не правы в отношении вектора , содержащего только строки.

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