Векторы в Java, как вернуть несколько векторов в объекте

Я работаю над 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;
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
7 445
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Прежде всего, используйте ArrayList вместо Vector. Затем используйте Map в качестве возвращаемого объекта, при этом каждое значение записи является одним из ваших списков.

Во-вторых, гораздо лучший подход - создать объект, который фактически содержит каждое из ваших полей и возвращает список этих объектов java.util.List.

public class Item
{
    String id;
    String name
    Integer pOrdered;        
    Integer inStore;
           :
           :

Ага, насчет ArrayList, это «относительно новое» дополнение к Java? Потому что моя (не очень хорошая) книга о них не говорит ... Хммм ... Мне определенно нужна новая книга по Java ... Спасибо за вашу помощь!

Danielle 27.11.2008 00:13

Он был добавлен в J2SE 1.5, так что ... 2004? Что-то вроде того.

Adam Jaskiewicz 27.11.2008 00:21

ArrayList был добавлен в версию 1.2, декабрь 1998 г. (вау! Так долго ?!). Это должно быть рассмотрено в разделе «Коллекции Java».

James Schek 27.11.2008 00:23

Да ладно, перепутал это со всеми улучшениями коллекций в 1.5. Сколько лет вашей книге по Java? Не могли бы вы ударить этим своего учителя за то, что он использовал книгу 10-летней давности для преподавания курса Java?

Adam Jaskiewicz 27.11.2008 00:31

эй, некоторые из нас застряли в написании кода, который работает на Java 1.1 (чертовски MS JVM ...). Никаких новых игрушек у нас нет ...

Herms 27.11.2008 01:03

Извините, но все, что я могу сказать по этому поводу, это ... eeeeeeeeeeeeeeeeeww.

Adam Jaskiewicz 27.11.2008 03:17
Ответ принят как подходящий

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

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, так что немного запутался ...

Danielle 27.11.2008 00:11

Вам действительно стоит пересмотреть свой дизайн здесь. У вас есть несколько векторов, каждый со свойствами одного и того же типа вещи - предмета в вашем инвентаре. Вам, вероятно, следует превратить это в отдельный класс, возможно, InventoryItem, с членами для имени, цены и т. д. Затем, при чтении каждого элемента, вы создаете InventoryItem с заданными свойствами и возвращаете один Vector<InventoryItem>.

Если вы действительно привязаны к отслеживанию всех этих отдельных Vector, вы можете просто вернуть Vector[] со всеми имеющимися у вас векторами:

return new Vector[] { itemID, itemName, pOrdered, pInStore, pSold, manufPrice, sellingPrice };

Кроме того, как говорит Робин, вы должны использовать контейнер ArrayList вместо Vector. Единственное, что изменится, это то, что вам нужно изменить все вызовы с someVector.AddElement на someList.add.

Я могу использовать это в крайнем случае, так как я все еще новичок в Java, и, честно говоря, я только что вышел из класса C++ и путаю два языка ... Создание класса звучит как хорошая идея, спасибо !

Danielle 27.11.2008 00:10

В C++ вы, вероятно, использовали бы для этого «структуру». Структура - это (в основном) класс, для всех членов которого по умолчанию установлено значение «public».

James Schek 27.11.2008 00:24

Похоже, это должно быть помечено как "Домашнее задание".

Хорошо, во-первых, вы обязаны использовать все эти векторы или это ваше собственное решение? Хотя некоторые могут указать, что использование ArrayLists лучше, я бы покончил с ними и создал свой собственный класс Item.

Таким образом, вместо того, чтобы иметь свойства концептуального элемента, распределенные по нескольким векторам (как вы это делаете сейчас), у вас есть 1 экземпляр элемента для каждого элемента с полями для всех данных, относящихся к этому элементу. Теперь вам нужна только одна структура данных (Vector или ArrayList) для всех ваших объектов item, и вы можете вернуть эту структуру из getInventory ().

Спасибо, я не подумал пометить это домашнее задание ... Я все еще новичок на этом сайте. И причина того, что это так, в том, что книга, над которой я работаю, отстой, если быть довольно резкой. Книга говорит нам делать это таким образом, но я думаю, что собираюсь изменить свой подход, спасибо!

Danielle 27.11.2008 00:09

Вы делаете несколько вещей неправильно.

Во-первых, не используйте вектор. Как обычно. Если для вас важен порядок, вам нужен List в API (и, возможно, ArrayList или LinkedList в качестве реализации).

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

В-третьих: не ловите это исключение. Вы не знаете, что с этим делать, и просто запутаете себя. Ловите исключение только в том случае, если у вас есть хорошая идея В самом деле, что делать в случае ошибки (вывод сообщения об ошибке без стека почти никогда не является правильным решением).

Подпись вашего метода - самая важная часть. Если вы все правильно поняли, реализация не имеет большого значения. Нацельтесь на что-то похожее на это:

List<Item> getInventory(File input) throws IOException {
}

Исключение было изначально размещено, потому что я не мог загрузить файл без него. Раньше у меня не было этой проблемы, но когда я не использовал блок try ... catch, возникали ошибки. Я собираюсь попробовать поработать с классом, как многие из вас уже сказали, спасибо!

Danielle 27.11.2008 00:12

AFAIK, java - это первый язык, на котором проводится эксперимент «проверенных исключений». В большинстве случаев это заканчивается неудачей из-за подобных случаев. По теме написано много: rockstarprogrammer.org/post/2007/jun/09/…

Dustin 27.11.2008 00:17

Самый простой способ объявить объект - это что-то вроде

List<Vector<? extends Object>> inventoryItem = new ArrayList<Vector<? extends Object>>

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

Однако похоже, что это действительно упускает суть. Вместо этого вы должны определить InventoryItem, у которого есть каждое из ваших семи полей. Каждый раз, когда вы читаете объект из файла, создайте экземпляр нового InventoryItem и заполните его поля. Затем вы добавляете это к одному вектору.

Кроме того, обычно не рекомендуется использовать класс Vector. Вместо этого вы должны использовать ArrayList. Вектор действительно следует использовать только в том случае, если вам нужны его свойства синхронизации, и даже тогда вам следует подумать о переносе какого-либо другого списка в Collections.synchronizedList ().

Наконец, места, где вы хотели бы поймать только Exception, можно пересчитать по пальцам. Вы действительно должны перехватить IOException, и даже если вы захотите просто повторно выбросить его. Кроме того, для исключения следует вызывать printStackTrace (), а не System.out.println ().

Спасибо за совет, это похоже на то, что все говорят. Надеюсь, вы все простите меня за новизну :) Но, эй, я ничего не узнаю, если не буду задавать вопросы, верно? Я, наверное, буду создавать класс. Спасибо!

Danielle 27.11.2008 00:24

Хотя в целом я полностью согласен с советом использовать List / ArrayList вместо Vector, важно знать, почему. В самом деле, я должен категорически не согласиться с Дастином, который говорит, что «никогда» не использовать Vector.

Вектор, по сути, является синхронизированным списком массивов. Если вам действительно нужна синхронизация, во что бы то ни стало, проигнорируйте наставления Дастина и используйте Vector.

Есть еще один случай, когда вектор оправдан. И тогда вам нужно поддерживать совместимость с базой кода до Java2.

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

Danielle 27.11.2008 00:21

Джордж - это неверно. Если вам нужен список синхронизированных массивов, лучше всего использовать «Collections.synchronizedList (new ArrayList ())».

James Schek 27.11.2008 00:26

Если вам действительно нужна потокобезопасность, использование класса с каждым синхронизируемым методом не даст вам этого. Вы должны продумать все возможные проблемы с синхронизацией. Vector является потокобезопасным только в том смысле, что он не повреждается. Collections.synchronizedList работает для любого списка, если этого достаточно

Dustin 27.11.2008 00:29

Дастин - хорошее замечание. Это очевидно по некоторым коллекционным и «примитивным» типам, доступным через java.util.concurrent, таким как Concurrent HashMap и атомарные примитивы.

James Schek 27.11.2008 00:46

Джеймс: не поможет, если вам нужна обратная совместимость с кодовой базой до Java2. Дастин: Я сказал, что если вам нужна синхронизация ArrayList, я сделал нет адресной потокобезопасностью в целом.

Dexygen 27.11.2008 01:22

Ирония заключается в том, что я использовал те же аргументы в качестве руководителя группы в моем последнем контракте против с использованием Vector, им тоже не понравился мой ответ. Разве судьи не говорят, что, когда ни одной из сторон не нравится их решение, они знают, что это было правильно?

Dexygen 27.11.2008 01:24

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

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

Нет причин не создавать бизнес-класс, который содержит ваши коллекции вместе с бизнес-логикой для управления ими (да, всегда есть бизнес-логика - это код копирования и вставки, который вы найдете в местах, где вы получаете доступ к коллекции ).

Раньше меня расстраивало то, что JDK всегда, кажется, принимает массивы встроенных типов, а не коллекции, но это имеет гораздо больший смысл после того, как примирился с идеей, что передача коллекций (например, передача любого базового типа) просто не очень хорошая идея.

Другие вопросы по теме