2014-11-14 6 views
1

Я ищу идею, как выполнить эту задачу. Поэтому я начну с того, как работает моя программа.Java sanitizing Arraylist записи предложения

Моя программа читает файл CSV. Они представляют собой пары ключевых значений, разделенные запятой.

L1234456,ygja-3bcb-iiiv-pppp-a8yr-c3d2-ct7v-giap-24yj-3gie 
    L6789101,zgna-3mcb-iiiv-pppp-a8yr-c3d2-ct7v-gggg-zz33-33ie 

и т.д.

Функция принимает имя файла и разбирает его в ArrayList из String []. Функция возвращает ArrayList.

public ArrayList<String[]> parseFile(File csvFile) { 
    Scanner scan = null; 
    try { 
     scan = new Scanner(csvFile); 
    } catch (FileNotFoundException e) { 

    } 

    ArrayList<String[]> records = new ArrayList<String[]>(); 
    String[] record = new String[2]; 
    while (scan.hasNext()) { 
     record = scan.nextLine().trim().split(","); 
     records.add(record); 
    } 
    return records; 
} 

Вот код, в котором я собираю файл синтаксического анализа и передаю его в CSVFile.

ArrayList<String[]> Records = parseFile(csvFile); 

Я создал другой ArrayList для файлов, которые не были проанализированы.

ArrayList<String> NotParsed = new ArrayList<String>(); 

Таким образом, программа затем продолжает дезинфицировать пары значений ключа, разделенные запятой. Поэтому мы сначала начинаем с первого ключа в записи. Например, L1234456. Если запись не может быть дезинфицирована, она заменяет текущий ключ текстом «CouldNOtBeParsed».

for (int i = 0; i < Records.size(); i++) { 
     if(!validateRecord(Records.get(i)[0].toString())) { 
      Logging.info("Records could not be parsed " + Records.get(i)[0]); 
       NotParsed.add(srpRecords.get(i)[0].toString()); 
      Records.get(i)[0] = "CouldNotBeParsed"; 
     } else { 
      Logging.info(Records.get(i)[0] + " has been sanitized"); 
     } 
    } 

Далее мы делаем 2-й ключ в паре значение, например ygja-3bcb-IIIV-PPPP-a8yr-c3d2-ct7v-Гиап-24yj-3gie

for (int i = 0; i < Records.size(); i++) { 
     if(!validateRecordKey(Records.get(i)[1].toString())) { 
      Logging.info("Record Key could not be parsed " + Records.get(i)[0]); 
       NotParsed.add(Records.get(i)[1].toString()); 
      Records.get(i)[1] = "CouldNotBeParsed"; 
     } else { 
      Logging.info(Records.get(i)[1] + " has been sanitized"); 
     } 
    } 

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

Я подумал о том, что цикл зациклился на записи и удалил записи с текстом «CouldNotBeParsed», чтобы просто оставить те, которые могут быть проанализированы. Я также попытался удалить записи из цикла for Records.remove ((i)); Однако это путает цикл For, потому что, если первая запись не может быть дезинфицирована, то она удаляется, а на следующей итерации цикла она пропускается, потому что запись 2 теперь является записью 1. Вот почему я пошел с добавлением текста.

На самом деле мне нужны два списка, один для записей, которые были дезинфицированы, а другой - нет.

Так что я думал, что должен быть лучший способ сделать это. Или лучший способ обезопасить пары keyValue в одно и то же время или что-то в этом роде. Предложения?

ответ

1

Начало путем изменения структуры данных: вместо того, чтобы использовать список из двух элементов String[] массивов, определить класс для пар ключ-значение:

class KeyValuePair { 
    private final String key; 
    private final String value; 
    public KeyValuePair(String k, String v) { key = k; value = v; } 
    public String getKey() { return key; } 
    public String getValue() { return value; } 
} 

Обратите внимание, что класс является неизменяемым.

Теперь создадим объект с тремя списками из KeyValuePair объектов:

class ParseResult { 
    private final List<KeyValuePair> sanitized = new ArrayList<KeyValuePair>(); 
    private final List<KeyValuePair> badKey = new ArrayList<KeyValuePair>(); 
    private final List<KeyValuePair> badValue = new ArrayList<KeyValuePair>(); 
    public ParseResult(List<KeyValuePair> s, List<KeyValuePair> bk, List<KeyValuePair> bv) { 
     sanitized = s; 
     badKey = bk; 
     badValue = bv; 
    } 
    public List<KeyValuePair> getSanitized() { return sanitized; } 
    public List<KeyValuePair> getBadKey() { return badKey; } 
    public List<KeyValuePair> getBadValue() { return badValue; } 
} 

Наконец, заполнить эти три списка в одном цикле, который считывает из файла:

public static ParseResult parseFile(File csvFile) { 
    Scanner scan = null; 
    try { 
     scan = new Scanner(csvFile); 
    } catch (FileNotFoundException e) { 
     ??? 
     // Do something about this exception. 
     // Consider not catching it here, letting the caller deal with it. 
    } 
    final List<KeyValuePair> sanitized = new ArrayList<KeyValuePair>(); 
    final List<KeyValuePair> badKey = new ArrayList<KeyValuePair>(); 
    final List<KeyValuePair> badValue = new ArrayList<KeyValuePair>(); 
    while (scan.hasNext()) { 
     String[] tokens = scan.nextLine().trim().split(","); 
     if (tokens.length != 2) { 
      ??? 
      // Do something about this - either throw an exception, 
      // or log a message and continue. 
     } 
     KeyValuePair kvp = new KeyValuePair(tokens[0], tokens[1]); 
     // Do the validation on the spot 
     if (!validateRecordKey(kvp.getKey())) { 
      badKey.add(kvp); 
     } else if (!validateRecord(kvp.getValue())) { 
      badValue.add(kvp); 
     } else { 
      sanitized.add(kvp); 
     } 
    } 
    return new ParseResult(sanitized, badKey, badValue); 
} 

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

+0

Спасибо, что делает кучу больше смысла и является более эффективным способом делать что-то. Итак, теперь у меня есть ParseResult Records = parseFile (csvFile); и я могу видеть мой badkey, badValue и Sanitized. Последний вопрос, как я зацикливаюсь, хотя Records только для того, чтобы пинтовать, говорят только плохие записи или, возможно, только санированные записи и т. Д.? Например, я хочу только передать Sanitized records в другую функцию. Например, до того, как я передал записи в мою подготовленную функцию оператора, например ps (Records). Думаю, как бы я только передал дезинфицированные записи в функцию PS? – user1158745

+0

@ user1158745 Теперь, когда у вас есть 'ParseResult Records', вы можете взять отдельные списки, используя свои геттеры, например, следующим образом:' saveToDatabase (Records.getSanitized()); ' – dasblinkenlight

+0

Последний вопрос для вашего. Как бы я взял классы и поместил их в свой собственный файл и ссылался на них в коде orignal, чтобы просто очистить вещи? – user1158745