Я работаю над java-программой, и у меня есть несколько векторов, определенных и заполненных (из файла) внутри метода. Мне нужно вернуть содержимое всех векторов из метода. Я слышал, что вы можете поместить их все в один объект, чтобы вернуть их. Возможно ли это, и если да, то как? Если нет, есть ли у вас для меня какие-нибудь возможные решения? Заранее спасибо за помощь!
Вот фрагмент кода:
Object getInventory()
{
Vector<String> itemID=new Vector<String>();
Vector<String> itemName=new Vector<String>();
Vector<Integer> pOrdered=new Vector<Integer>();
Vector<Integer> pInStore=new Vector<Integer>();
Vector<Integer> pSold=new Vector<Integer>();
Vector<Double> manufPrice=new Vector<Double>();
Vector<Double> sellingPrice=new Vector<Double>();
Object inventoryItem=new Object(); //object to store vectors in
try
{
Scanner infile= new Scanner(new FileReader("Ch10Ex16Data.txt"));
int i=0;
while (infile.hasNext())
{
itemID.addElement(infile.next());
itemName.addElement(infile.next()+infile.nextLine());
pOrdered.addElement(infile.nextInt());
pInStore.addElement(pOrdered.elementAt(i));
pSold.addElement(0);
manufPrice.addElement(infile.nextDouble());
sellingPrice.addElement(infile.nextDouble());
i++;
}
infile.close();
System.out.println(itemID);
System.out.println(itemName);
System.out.println(pOrdered);
System.out.println(pInStore);
System.out.println(pSold);
System.out.println(manufPrice);
System.out.println(sellingPrice);
}
catch (Exception f)
{
System.out.print(f);
}
return inventoryItem;
}




Прежде всего, используйте ArrayList вместо Vector. Затем используйте Map в качестве возвращаемого объекта, при этом каждое значение записи является одним из ваших списков.
Во-вторых, гораздо лучший подход - создать объект, который фактически содержит каждое из ваших полей и возвращает список этих объектов java.util.List.
public class Item
{
String id;
String name
Integer pOrdered;
Integer inStore;
:
:
Он был добавлен в J2SE 1.5, так что ... 2004? Что-то вроде того.
ArrayList был добавлен в версию 1.2, декабрь 1998 г. (вау! Так долго ?!). Это должно быть рассмотрено в разделе «Коллекции Java».
Да ладно, перепутал это со всеми улучшениями коллекций в 1.5. Сколько лет вашей книге по Java? Не могли бы вы ударить этим своего учителя за то, что он использовал книгу 10-летней давности для преподавания курса Java?
эй, некоторые из нас застряли в написании кода, который работает на Java 1.1 (чертовски MS JVM ...). Никаких новых игрушек у нас нет ...
Извините, но все, что я могу сказать по этому поводу, это ... eeeeeeeeeeeeeeeeeww.
Лично я бы полностью отказался от этого подхода. Похоже, вам нужен класс продукта:
public class Product {
private String itemName;
private int itemID;
// etc etc
public Product(String itemName, int itemID) {
this.itemName = itemName;
this.itemID = itemID;
// etc etc
}
public String getItemName() {
return itemName;
}
public int getItemID() {
return itemID;
}
// etc etc
}
Тогда примерно так:
public class Invertory {
private List<Product> products = new ArrayList<Product>
// etc etc
public Inventory(String fileName) throws IOException {
// Load file,
// Read each product,
products.add(new Product(...product arguments); //add to array
}
public Product[] getProducts() {
return products.toArray(new Product[]{});
}
}
Спасибо за подробное описание, я, вероятно, сошлюсь на него, чтобы сделать это, спасибо! Как я уже сказал, все еще новичок в Java, так что немного запутался ...
Вам действительно стоит пересмотреть свой дизайн здесь. У вас есть несколько векторов, каждый со свойствами одного и того же типа вещи - предмета в вашем инвентаре. Вам, вероятно, следует превратить это в отдельный класс, возможно, InventoryItem, с членами для имени, цены и т. д. Затем, при чтении каждого элемента, вы создаете InventoryItem с заданными свойствами и возвращаете один Vector<InventoryItem>.
Если вы действительно привязаны к отслеживанию всех этих отдельных Vector, вы можете просто вернуть Vector[] со всеми имеющимися у вас векторами:
return new Vector[] { itemID, itemName, pOrdered, pInStore, pSold, manufPrice, sellingPrice };
Кроме того, как говорит Робин, вы должны использовать контейнер ArrayList вместо Vector. Единственное, что изменится, это то, что вам нужно изменить все вызовы с someVector.AddElement на someList.add.
Я могу использовать это в крайнем случае, так как я все еще новичок в Java, и, честно говоря, я только что вышел из класса C++ и путаю два языка ... Создание класса звучит как хорошая идея, спасибо !
В C++ вы, вероятно, использовали бы для этого «структуру». Структура - это (в основном) класс, для всех членов которого по умолчанию установлено значение «public».
Похоже, это должно быть помечено как "Домашнее задание".
Хорошо, во-первых, вы обязаны использовать все эти векторы или это ваше собственное решение? Хотя некоторые могут указать, что использование ArrayLists лучше, я бы покончил с ними и создал свой собственный класс Item.
Таким образом, вместо того, чтобы иметь свойства концептуального элемента, распределенные по нескольким векторам (как вы это делаете сейчас), у вас есть 1 экземпляр элемента для каждого элемента с полями для всех данных, относящихся к этому элементу. Теперь вам нужна только одна структура данных (Vector или ArrayList) для всех ваших объектов item, и вы можете вернуть эту структуру из getInventory ().
Спасибо, я не подумал пометить это домашнее задание ... Я все еще новичок на этом сайте. И причина того, что это так, в том, что книга, над которой я работаю, отстой, если быть довольно резкой. Книга говорит нам делать это таким образом, но я думаю, что собираюсь изменить свой подход, спасибо!
Вы делаете несколько вещей неправильно.
Во-первых, не используйте вектор. Как обычно. Если для вас важен порядок, вам нужен List в API (и, возможно, ArrayList или LinkedList в качестве реализации).
Во-вторых, вы пытаетесь иметь большое количество массивов, значения которых совпадают. Это будет практически невозможно использовать. Просто создайте класс, представляющий одну запись, и верните их список.
В-третьих: не ловите это исключение. Вы не знаете, что с этим делать, и просто запутаете себя. Ловите исключение только в том случае, если у вас есть хорошая идея В самом деле, что делать в случае ошибки (вывод сообщения об ошибке без стека почти никогда не является правильным решением).
Подпись вашего метода - самая важная часть. Если вы все правильно поняли, реализация не имеет большого значения. Нацельтесь на что-то похожее на это:
List<Item> getInventory(File input) throws IOException {
}
Исключение было изначально размещено, потому что я не мог загрузить файл без него. Раньше у меня не было этой проблемы, но когда я не использовал блок try ... catch, возникали ошибки. Я собираюсь попробовать поработать с классом, как многие из вас уже сказали, спасибо!
AFAIK, java - это первый язык, на котором проводится эксперимент «проверенных исключений». В большинстве случаев это заканчивается неудачей из-за подобных случаев. По теме написано много: rockstarprogrammer.org/post/2007/jun/09/…
Самый простой способ объявить объект - это что-то вроде
List<Vector<? extends Object>> inventoryItem = new ArrayList<Vector<? extends Object>>
но здесь есть несколько проблем, а именно то, что дженерики Java не реифицируются, поэтому вам нужно тестировать и приводить содержимое каждого возвращаемого вектора. Лучшим решением было бы определить объект-контейнер, который имеет каждый из векторов как поля, и добавить к ним.
Однако похоже, что это действительно упускает суть. Вместо этого вы должны определить InventoryItem, у которого есть каждое из ваших семи полей. Каждый раз, когда вы читаете объект из файла, создайте экземпляр нового InventoryItem и заполните его поля. Затем вы добавляете это к одному вектору.
Кроме того, обычно не рекомендуется использовать класс Vector. Вместо этого вы должны использовать ArrayList. Вектор действительно следует использовать только в том случае, если вам нужны его свойства синхронизации, и даже тогда вам следует подумать о переносе какого-либо другого списка в Collections.synchronizedList ().
Наконец, места, где вы хотели бы поймать только Exception, можно пересчитать по пальцам. Вы действительно должны перехватить IOException, и даже если вы захотите просто повторно выбросить его. Кроме того, для исключения следует вызывать printStackTrace (), а не System.out.println ().
Спасибо за совет, это похоже на то, что все говорят. Надеюсь, вы все простите меня за новизну :) Но, эй, я ничего не узнаю, если не буду задавать вопросы, верно? Я, наверное, буду создавать класс. Спасибо!
Хотя в целом я полностью согласен с советом использовать List / ArrayList вместо Vector, важно знать, почему. В самом деле, я должен категорически не согласиться с Дастином, который говорит, что «никогда» не использовать Vector.
Вектор, по сути, является синхронизированным списком массивов. Если вам действительно нужна синхронизация, во что бы то ни стало, проигнорируйте наставления Дастина и используйте Vector.
Есть еще один случай, когда вектор оправдан. И тогда вам нужно поддерживать совместимость с базой кода до Java2.
Спасибо за совет, буду иметь это в виду. Я действительно считаю, что мне нужно провести много исследований. Между тем, что мой инструктор был старой школой java, отстойной книгой и всем этим, мне нужно исправить это в моей голове!
Джордж - это неверно. Если вам нужен список синхронизированных массивов, лучше всего использовать «Collections.synchronizedList (new ArrayList ())».
Если вам действительно нужна потокобезопасность, использование класса с каждым синхронизируемым методом не даст вам этого. Вы должны продумать все возможные проблемы с синхронизацией. Vector является потокобезопасным только в том смысле, что он не повреждается. Collections.synchronizedList работает для любого списка, если этого достаточно
Дастин - хорошее замечание. Это очевидно по некоторым коллекционным и «примитивным» типам, доступным через java.util.concurrent, таким как Concurrent HashMap и атомарные примитивы.
Джеймс: не поможет, если вам нужна обратная совместимость с кодовой базой до Java2. Дастин: Я сказал, что если вам нужна синхронизация ArrayList, я сделал нет адресной потокобезопасностью в целом.
Ирония заключается в том, что я использовал те же аргументы в качестве руководителя группы в моем последнем контракте против с использованием Vector, им тоже не понравился мой ответ. Разве судьи не говорят, что, когда ни одной из сторон не нравится их решение, они знают, что это было правильно?
Я считаю, что хорошее эмпирическое правило состоит в том, что передавать коллекции за пределами ваших объектов никогда не является хорошей идеей. Они, очевидно, полезны внутри вашего объекта, но снаружи вы теряете контроль, и они не очевидны.
Подумайте о том, как сделать ваш код читабельным, а не документировать его. Если вы возьмете коллекцию, как она скажет вызывающему, что передать? Даже если вы используете дженерики, невозможно установить контроль над тем, что происходит с коллекцией - кто-то может добавлять к ней и удалять из нее в другом потоке после того, как она передана вам.
Нет причин не создавать бизнес-класс, который содержит ваши коллекции вместе с бизнес-логикой для управления ими (да, всегда есть бизнес-логика - это код копирования и вставки, который вы найдете в местах, где вы получаете доступ к коллекции ).
Раньше меня расстраивало то, что JDK всегда, кажется, принимает массивы встроенных типов, а не коллекции, но это имеет гораздо больший смысл после того, как примирился с идеей, что передача коллекций (например, передача любого базового типа) просто не очень хорошая идея.
Ага, насчет ArrayList, это «относительно новое» дополнение к Java? Потому что моя (не очень хорошая) книга о них не говорит ... Хммм ... Мне определенно нужна новая книга по Java ... Спасибо за вашу помощь!