2014-11-14 7 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를 문자열로 그것을 파싱한다. 이 함수는 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"); 
     } 
    } 

다음으로 우리는 예를 들어 ygja-3bcb-iiiv-PPPP-a8yr-c3d2-ct7v-giap-24yj-3gie 키 값 쌍의 2 차 키를 할

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"); 
     } 
    } 

문제는 그 I 키 값 쌍을 모두 살균해야하고, 살균 될 수없는 keyValue 쌍과 그 목록이 새 니타 이징되어 데이터베이스에 삽입 될 수있는 별도의 목록을 만듭니다. 할 수없는 것들은 사용자에게 인쇄 될 것입니다.

나는 루핑에 대한 생각을 레코드를 제거하고 "CouldNotBeParsed"텍스트로 레코드를 제거하여 구문 분석 할 수있는 텍스트 만 남겨 두었습니다. 또한 for 루프에서 Records.remove ((i)) 중에 레코드를 제거하려고했습니다. 그러나 첫 번째 레코드를 삭제할 수 없으면 레코드의 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를 볼 수 있습니다. 마지막 질문인데, 레코드를 파인트로 치기 만해도 레코드가 잘못되거나 어쩌면 그냥 살균 된 레코드라고 말하는 것일까? 예를 들어, Sanitized 레코드를 다른 함수로 전달하기를 원합니다. 예를 들어 레코드를 준비된 명령문 함수 ps (Records)에 전달하기 전에 나는 PS 함수에 sanitized 레코드를 어떻게 전달할 것인가? – user1158745

+0

@ user1158745 이제'ParseResult Records'가 생겼으므로 getters를 사용하여 개별 목록을 가져올 수 있습니다 (예 :'saveToDatabase (Records.getSanitized());' – dasblinkenlight

+0

마지막 질문입니다. 클래스를 가져 와서 자신의 파일에 넣고 파일을 정리하기 위해 orignal 코드에서 참조하는 방법은 무엇입니까? – user1158745