0

I have different documents, one document is referring to one client for example and another document to another. I have Pdf(generic) class with methods that are shared between different Pdf documents > then i have a method that transforms a PDDocument type object to Page wrapper class.

How can i instead of creating Page , create a generic and return a lift of client.Page or client1,Page

 public List<Page> splitToPages() {
    try {
        Splitter splitter = new Splitter();
        return splitter.split(getPDDocument()).stream().map(Page::new).collect(Collectors.toList());
    } catch (IOException e) {
        throw new RuntimeException("Document could not be split", e);
    }
}

Thank you

1 Answers1

2

Pass in a Function which takes what comes out of the Splitter, and turns it into the type you want:

 public <T> List<T> splitToPages(Function<? super WhateverSplitterReturns, ? extends T> function) {
    try {
        Splitter splitter = new Splitter();
        return splitter.split(getPDDocument()).stream().map(function).collect(Collectors.toList());
    } catch (IOException e) {
        throw new RuntimeException("Document could not be split", e);
    }
}

which you can call with, e.g.

List<Page> pages = splitToPages(Page::new);
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Hey could you spend an extra minute and explain why we need to use super here – Artjom Prozorov Jan 13 '20 at 09:58
  • 1
    @ArtjomProzorov you don't *really*, it just makes the API more flexible. It just means "a function that can accept a `WhateverSplitterReturns`, even if it accepts more general types too". See [What is PECS](https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super), or the item in *Effective Java* "Use bounded wildcards to increase API flexibility" (Item 31 in 3rd Ed), or [Wildcards](https://docs.oracle.com/javase/tutorial/java/generics/wildcards.html) in the Java tutorial. – Andy Turner Jan 13 '20 at 09:59
  • Thank you a bunch – Artjom Prozorov Jan 13 '20 at 10:05