Какую коллекцию java использовать?

У меня возникли проблемы с выбором того, какая коллекция java лучше всего подходит для моего сценария. В настоящее время я читаю запись, которая дает мне «номер счета» и «имя клиента».

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

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

Существует ли определенный тип коллекции, который лучше всего подходит для этой цели (если таковой вообще существует)?

0
nl ja de
Номер счета и клиент уникальны вместе? Таким образом, вы можете использовать карту и сложный ключ.
добавлено автор BobTheBuilder, источник

4 ответы

Assuming you have sufficient memory, I would probably use a HashMap.

Где CustomerRecord - это объект, содержащий запись, которую вы ищете.

А затем создайте ключевой класс:

public class AccountIdentifier {
    public String accountNumber;
    public String customerName;

    public AccountIdentifier(String accountNumber, String customerName) {
        this.accountNumber = accountNumber;
        this.customerName = customerName;
    }
    public int hashCode() {
        return (accountNumber+"#"+customerName).hashCode();
    }

    public boolean equals(Object obj) {
        if(!(obj instanceof AccountIdentifier)) return false;
        else {
            AccountIdentifier id = (AccountIdentifier)obj;
            return accountNumber.equals(id.accountNumber) && customerName.equals(id.customerName);
        }
    }
}

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

theMap.put (accountIdentifier, customerRecord);

Когда наступает время поиска, и у вас есть номер счета и имя_пользователя из первого файла, выполните следующие действия:

AccountIdentifier accountIdentifier = new AccountIdentifier(accountNumber, customerName);
CustomerRecord record = theMap.get(accountIdentifier);

Заключительный комментарий, если ваш файл слишком велик, чтобы вписаться в память, вам следует подумать об использовании библиотеки кеша, например ehcache .

2
добавлено

Почему бы не сделать это еще быстрее?

Создание класса Клиент:

 public class Customer {
     private final int accountNumber;
     private final String customerName;

     public Customer (int accountNumber, String customerName) {
          this.accountNumber = accountNumber;
          this.customerName = customerName;
     }
     public boolean equals(Object o) {
          //check if accountNumber and customerName are equal
     } 
     public int hashCode() {
          return 13*accountNumber + 31*customerName.hashCode();
     }
 }
 public class CustomerBucket() {
     private final int forAccountNumber;
     private Map map = HashMap();
     public CustomerBucket(int forAccountNumber) {
         //...
     }
     public boolean equals(Object o) {
         return o.forAccountNumber == this.forAccountNumber;
     }
     public int hashCode() {
         return forAccountNumber;
     }
 }
 public class AccountSearcher {
     private final Set set = new HashSet();
     public Customer getCustomer(int accountNumber, String name) {
         return set.get(accountNumber).get(name);
     }
 }

Таким образом, вы можете искать записи почти в O (1). Этот подход также дает вам возможности для поиска accountNumbers (и возвращает список имен, связанных с этим числом).

1
добавлено

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

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

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

Бинарный поиск полезен только в том случае, если вы возвращаете только соответствие одному , как вы можете видеть по сигнатуре метода и , вам нужно отсортировать Collection до вызова двоичного поиска.

Итак, подводя итог:

  • Определите Comparator , который принимает два объекта Record и проверяет, имеют ли они одинаковый идентификатор/имя.

  • Загрузите все записи в ArrayList , например.

  • Отсортировать их.

  • Вызовите Collections.binarySearch с помощью вашей сортированной коллекции и вашего пользовательского компаратора.

1
добавлено

Your best bet is to create an object which contains both the account number and customer name. Then you can read in your customer file in to the a Map. Here, CustomerInfo is your object which contains just the customer name and account number, and FileInfo is your object which contains all of the information read from the file. Now you can do simple lookups against the map.

Обратите внимание, что вам нужно будет убедиться, что CustomerInfo реализует hashCode() и equals() , чтобы это работало правильно.

1
добавлено
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async