1

제 사례는 Java POJO를 CSV 문자열로 변환 할 수 있어야하는 일반 CSV 변환기를 작성하는 것이 었습니다.일반 POJO를 CSV 변환기로 작성하기

내 구현 :

public <T> List<String> convertToString(List<T> objectList) { 

     List<String> stringList = new ArrayList<>(); 
     char delimiter = ','; 
     char quote = '"'; 
     String lineSep = "\n"; 

     CsvMapper mapper = new CsvMapper(); 
     CsvSchema schema = mapper.schemaFor(!HOW_TO!); 

     for (T object : objectList) { 

      try { 
       String csv = mapper.writer(schema 
         .withColumnSeparator(delimiter) 
         .withQuoteChar(quote) 
         .withLineSeparator(lineSep)).writeValueAsString(object); 

      } catch (JsonProcessingException e) { 

       System.out.println(e); 
      } 
     } 

     return stringList; 
} 

내가 잭슨 DATAFORMAT-CSV 라이브러리를 사용했다,하지만 난 HOW_TO와 붙어있어! 부분, 즉 objectList로부터 객체의 .class를 추출하는 방법. 나는 공부하고 있었고 타입 삭제를 보았습니다. 그래서 저는 .class를 매개 변수로 내 함수에주는 것 외에는 불가능하다고 생각합니다. 하지만 Java Reflection을 사용하여 일반 개체에서이 개체 목록을 추출하기 때문에 .class 매개 변수를 제공하는 옵션을 사용할 수 없습니다.

해결 방법이 있습니까?

또는

내가 구분, 인용 부호, 라인 분리 등

감사를 추가하는 기능을 일반 List<T> objectList to List<String> csvList을 변환 할 수있는 다른 방법/라이브러리

!

답변

1

간단한 옵션이 있습니다. 코드에 코드를 추가하여 표시했습니다.

public <T> List<String> convertToString(List<T> objectList) { 

    if(objectList.isEmpty()) 
     return Collections.emptyList(); 

    T entry = objectList.get(0); 

    List<String> stringList = new ArrayList<>(); 
    char delimiter = ','; 
    char quote = '"'; 
    String lineSep = "\n"; 

    CsvMapper mapper = new CsvMapper(); 
    CsvSchema schema = mapper.schemaFor(entry.getClass()); 

    for (T object : objectList) { 

     try { 
      String csv = mapper.writer(schema 
        .withColumnSeparator(delimiter) 
        .withQuoteChar(quote) 
        .withLineSeparator(lineSep)).writeValueAsString(object); 

      stringList.add(csv); 
     } catch (JsonProcessingException e) { 
      System.out.println(e); 
     } 
    } 

    return stringList; 
} 

트릭은 목록의 요소 중 하나를 가져 오는 것입니다. 충돌을 피하기 위해 입력 목록에 항목이없는 경우 수정할 수없는 빈 목록을 반환하는 초기에 약간의 데이터 무결성 테스트를 추가했습니다. 그런 다음 Object의 인스턴스를 검색하고이를 사용하여 클래스를 가져옵니다. convertToString 방법은 매개 변수화 클래스에있는 경우

은 또는 당신

public class GenericClass<T> { 

private final Class<T> type; 

public GenericClass(Class<T> type) { 
     this.type = type; 
} 

public Class<T> getMyType() { 
    return this.type; 
} 
} 

이 솔루션은 당신이 당신이 필요합니다 생각하지 않습니다 T.의 클래스를 얻을 수 있도록 약간 다른 방법으로 그렇게 할 수 이 질문에 대해서는 도움이 될 수 있습니다.

+0

목록의 첫 번째 요소가 목록의 다른 요소와 공유되지 않는 하위 클래스 일 경우 어떻게 될까요? –

+0

그때는 문제가되지 않습니다. 목록입니다. 목록을 통해 수퍼 클래스로 알려져 있습니다. 서브 클래스를 처리하기 위해 매퍼가 필요할 경우 솔루션은 간단합니다.for 루프에서 스키마를 다시 작성하고 각 요소에서 동일한 getClass를 수행하면된다. 그의 예에서 그는 자신의 스키마를 루프 밖으로 설정 했으므로 목록의 모든 요소는 동일한 방식으로 처리되어야한다고 가정했습니다. 따라서 특별한 경우가 필요 없습니다. –

+0

예, 중요합니다. 'List '이 주어지면, 모든 요소를 ​​똑같이 다루기를 원하면'Class'는'MyBaseClass'입니다. 그러나 요소 0이 런타임 유형이 'SubclassA'인 인스턴스를 가리킨다면 메소드는 자신이 'List '을 가지고 있다고 확신하게 될 것이고 다른 모든 인스턴스도 그 일이 아니라면 빨리 문제가 발생할 것입니다 아강. 귀하의 진술은 "그것은 수퍼 클래스로서 목록을 통해 알려져 있습니다"잘못된 것입니다. 목록의 참조 유형은'Object'입니다. 런타임 유형은 실제 서브 클래스 유형입니다. 컴파일시에만 기본 클래스로 알려져 있습니다. –

0

이 문제는 대부분의 사람들이 Java가 제네릭을 수행하는 방식의 결과로보기를 원하는 것보다 어렵다고 생각됩니다. Bruno의 대답은 특정 가정을하거나 코드를 특정 방식으로 구성 할 수있는 경우 사용할 수있는 옵션을 보여줍니다. http://blog.xebia.com/acessing-generic-types-at-runtime-in-java/

이는 방법을 설명합니다 : 당신이 기사에 대한 링크를 찾을 수 있습니다에서 How to get a class instance of generics type T

:

귀하의 경우에 작동합니다 또 다른 옵션이 다른 질문에 대한 답변의 방법으로 찾을 수 있습니다 객체의 슈퍼 클래스의 ParameterizedType을 사용합니다. List 개체에이를 적용 할 수 있습니다. 잘하면 잘될 것입니다. 이것은 당신이 필요로하는 것과 타입 매개 변수가 일치하는 수퍼 클래스를 가진 객체를 매개 변수로 취하기 때문에이 경우 운 좋게 만 작동 할 수 있습니다.

실제로 일반적으로 우리는 런타임에 형식 매개 변수를 알 수 없습니다. 유형 토큰 (Class<T>의 매개 변수)