Home > Blockchain >  I need a method that returns only one or several list object fields
I need a method that returns only one or several list object fields

Time:07-28

I have a method that writes an object to a file for all fields, I need a method that writes only selected fields to a file

public  void makeSCV(List<String> fields){
        String name = "";
        String FILE_NAME= "C:\\Users\\Admin\\Documents\\files.csv";
        try {
          PrintWriter pw= new PrintWriter(new File(FILE_NAME));
          StringBuilder sb=new StringBuilder();
          List<Customer> list = customerRepository.findAll();
          for(Customer obj : list){
            name = obj.getFullName() ","  obj.getId() "," obj.getEmail()
                 "," obj.getPhone() "," obj.getCreated() "," obj.getUpdated() "\r\n";
            sb.append(name);
          }
          pw.write(sb.toString());
          pw.close();
        } catch (Exception e) {
          // TODO: handle exception
        }
    
      }

CodePudding user response:

You can use Reflection for this. This way, there is no hard-coded behavior, so you can add fields and change the order at any time without changing the code, even at runtime!

public static void makeSCV(List<String> fields, List<Customer> customers) throws IOException {
    // Get desired fields via reflection
    var outPutFields = Arrays.stream(Customer.class.getDeclaredFields())
            .filter(o1 -> fields.contains(o1.getName())) // Only specified fields
            .sorted(Comparator.comparingInt(o -> fields.indexOf(o.getName()))) // Order like specified
            .peek(field -> field.setAccessible(true)) // For private fields
            .collect(Collectors.toList());

    var csvString = customers.stream()
            .map(customer -> outPutFields.stream()
                    .map(field -> {
                        try {
                            return field.get(customer).toString(); // get value of field for given object
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException(e);
                        }
                    })
                    .collect(Collectors.toList())
                    .toArray(new String[]{})
            )
            .map(objects -> String.join(",", objects)) // single csv line
            .collect(Collectors.joining("\r\n")); /// join csv lines

    // Write to file
    Files.write(Path.of("/path/to/outputFile.csv"), csvString.getBytes(StandardCharsets.UTF_8));
}

CodePudding user response:

You can make it more generic by adding diff methods in the Customer model.

i.e

class Customer {
    //properties

  public String getCustomerDetails(String type) {
     switch(type) {
        case "ONE":
           return obj.getFullName();
        case "TWO":
           return obj.getFullName() ","  obj.getId();
        case "THREE":
           return obj.getFullName() ","  obj.getId() "," obj.getEmail();

        ...
        default:
        ...   
}

}

Then you can update your method and pass the type as an argument.

i.e

public  void makeSCV(List<String> fields, String type){
        String name = "";
        String FILE_NAME= "C:\\Users\\Admin\\Documents\\files.csv";
        try {
          PrintWriter pw= new PrintWriter(new File(FILE_NAME));
          StringBuilder sb=new StringBuilder();
          List<Customer> list = customerRepository.findAll();
          for(Customer obj : list){
            sb.append(obj.getCustomerDetails(type));
          }
          pw.write(sb.toString());
          pw.close();
        } catch (Exception e) {
          // TODO: handle exception
        }
    
      }
  • Related