2010-08-04 3 views
4

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

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 класс: как принято отвечающему указывает, что это, вероятно, code smell, и вы, вероятно, нужно refactor код в иерархии классов.

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

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

+0

Единственное, что можно сказать об этом, - это использовать новый ArrayList (objects.size()), который инициализирует список с правильным размером. Вы не можете получить быстрее, чем O (n). – f1sh

+0

Примечание: я не * хочу * создать независимый вектор. Известно, что исходный вектор содержит все строки. Единственное, что блокирует программу, зная, что это все строки, - это тот факт, что общая метка вектора равна . Если бы был способ магически перевернуть ярлык , ничего не нужно было бы делать с элементами, так как они уже являются Строками.Таким образом, это можно технически сделать в O (1), хотя я понимаю, что языковые ограничения Java делают невозможным. –

ответ

6

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

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

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; 

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

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

+0

+1. Ударьте меня на минуту с этим ответом: o –

+0

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

+0

Спасибо за комментарий о запахе кода. Я фактически исправил всю эту ситуацию, создав общий коллектив CollectionSuperClass. Затем я запустил эту функцию, возвращая '' в 'CollectionSuperClass', а затем перевернул ее, чтобы вернуть' 'в' CollectionSubClass extends CollectionSuperClass '(обратите внимание: на другую коллекцию, специфичную для домена) «классы и классы элементов были использованы в фактическом коде). –

3

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

Вы нашли это для Фактически быть узким местом в вашем коде? И есть ли причина, почему вы используете Vector вместо ArrayList?

+0

Нет, на самом деле я не пытаюсь создать независимую коллекцию. В коде я знаю, что исходная коллекция содержит строки. Они изложены только как объекты из-за наследования. Если бы был способ заставить общий вектор быть вместо , это было бы идеально. Потенциал такого рода изменения поверхностной общей метки (поскольку все объекты известны как строки), поэтому я думал, что это может быть O (1). –

+0

@credford: вы можете реализовать 'List ' в смысле обертки - но не будет ничего, чтобы помешать вредоносному коду добавлять в коллекцию нестроку. Конечно, вы можете просто нарисовать 'Vector ' и аннотировать сообщение о времени компиляции, которое выполнило бы то же самое ... –

+0

Хорошо. Кастинг для 'Vector ' и аннотирование предупреждения о компиляции - это одно решение O (1), о котором я не думал. Хотя, я бы предпочел метод, который был в пределах ограничений языка. Кроме того, если бы существовал метод, который требовал ** меньшего набора текста **, это было бы столь же ценно для меня (поскольку O (n) не является узким местом). –

2

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

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

+0

Примечание: Оригинальный вектор , как известно, содержит все строки. Единственное, что блокирует программу, зная, что это все строки, - это тот факт, что общая метка вектора равна . Если бы был способ магически перевернуть ярлык , ничего не нужно было бы делать с элементами, так как они уже являются Строками. Таким образом, это можно технически сделать в O (1), хотя я понимаю, что языковые ограничения Java делают невозможным. –

1

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

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

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

1

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

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

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

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

0

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

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

+0

Я использовал Object только для того, чтобы сделать тип typecast, который мне нужен. В фактическом коде используется пользовательский класс и его пользовательский суперкласс. –

0

Вы пытаетесь использовать функцию времени выполнения для удаления функции времени компиляции; generics <String> все равно лишается.

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

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

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

Смежные вопросы