Question

I was looking at some examples using Guava to iterate embedded loops to analyze what fits better in this case.

Our environment uses java 6 and we need to create a excel parser using Apache POI.

Found this example with two embedded for loops:

FileInputStream file = new FileInputStream(new File("C:\\test.xls"));

//Get the workbook instance for XLS file 
HSSFWorkbook workbook = new HSSFWorkbook(file);

//Get first sheet from the workbook
HSSFSheet sheet = workbook.getSheetAt(0);

//Iterate through each rows from first sheet
for (Row row : sheet) {

    //For each row, iterate through each columns
    for (Cell cell : row) {

        switch(cell.getCellType()) {
            case Cell.CELL_TYPE_BOOLEAN:
                System.out.print(cell.getBooleanCellValue() + "\t\t");
                break;
            case Cell.CELL_TYPE_NUMERIC:
                System.out.print(cell.getNumericCellValue() + "\t\t");
                break;
            case Cell.CELL_TYPE_STRING:
                System.out.print(cell.getStringCellValue() + "\t\t");
                break;
        }
    }
    System.out.println("");
}

file.close();
FileOutputStream out = new FileOutputStream(new File("C:\\test.xls"));
workbook.write(out);
out.close();

I'd like to ask you what is the best way to iterate this, using while/for loops or guava filters? By the way, also found guava FluentIterable that may fit but I'm not so familiar with functional approaches.

Can you give me a hand? Thanks in advance

Was it helpful?

Solution

If you really want to play with a functional approach to solving this problem, you could implement a functor for Iterator, and map a function that formats a cell type over your rowIterator.

Unary function interface:

public interface Fn1<A,B> {
  B apply(A a);
}

A functor for Iterator:

public class IteratorFunctor<A> {

  public final Iterator<A> i;

  private IteratorFunctor(Iterator<A> _i) {
    i = _i;
  }

  public <B> IteratorFunctor<B> map(Fn1<A,B> f) {
    List<B> bs = new LinkedList<B>();
    while (i.hasNext()) {
      bs.add(f.apply(i.next()));
    }
    return apply(bs.iterator());
  }

  public static <A> IteratorFunctor<A> apply(Iterator<A> _i) {
    return new IteratorFunctor<A>(_i);
  }

}

A format function (for you, this would take a Cell and return perhaps a String):

public static String format(int x) {
  switch (x) {
    case 1:
      return "one";
    case 2:
      return "two";
    default:
      return "big";
  }
}

Demo:

Fn1<Integer,String> formatFn = new Fn1<Integer,String>() {
  public String apply(Integer x) {
    return format(x);
  }
};

List<Integer> xs = Arrays.asList(1,2,3,4);
IteratorFunctor<Integer> fi = IteratorFunctor.apply(xs.iterator());
IteratorFunctor<String> fs = fi.map(formatFn);
Iterator<String> ss = fs.i;

int i = 0;
while (ss.hasNext()) {
  System.out.println(i + ": " + ss.next());
  i = i + 1;
}

// Prints the following to stdout:
//
// 0: one
// 1: two
// 2: big
// 3: big
//
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top