2

How can I create a method that would accept a comparator with wildcard as argument, and then capture the class and use the comparator ?

public List<String> myFilter(Comparator<?> comp, Object value, Class c){
   return myList.stream()
         .filter(s->
              comp.compare(c.cast(s), c.cast(value))>=0
          ).collect(toList());
  }

EDIT: Ok, In fact, Andrew's answer is very interesting and works quite well :) Yet,given the comments, what I really should want is: instead of trying to cast within the method, expect that the cast had already been done within the comparator

so this would give:

  public List<String> filter(Comparator<String> comp){
         return myList.filter(s->comp.compare(s, null)>=0).collect(toList());
   }

and when calling it, this should be something like

   List<String> myNewList= filter((String s1, String s2)->{
                  try{
                      int i=Integer.parseInt(s1);
                      return Integer.compare(i, myRealCompareValue);
                 }catch(Exception e){
                      e.printStackTrace();
                     return null;
                 });

It doesn't look very nice though....

Myoch
  • 793
  • 1
  • 6
  • 24
  • 1
    What is the type of `myList` and how is it declared? – assylias Jul 25 '17 at 10:45
  • You can’t. Either, the comparator is correctly typed, or you can’t use it without an unchecked operation. – Holger Jul 25 '17 at 10:48
  • String. it is declared in the constructor of my class, that also accepts a List as argument. – Myoch Jul 25 '17 at 10:48
  • 1
    @Myoch why don't you use `Comparator` then? – talex Jul 25 '17 at 10:49
  • @talex because the list can contain numbers (and if so, all elements are numbers). – Myoch Jul 25 '17 at 10:50
  • Basically, myList can be one line (split given a delimiter) of the result of a call to Files.readAllLines() – Myoch Jul 25 '17 at 10:51
  • @Myoch `List` can't contain numbers (in fact it can, but it will be major design flaw). – talex Jul 25 '17 at 10:52
  • @Myoch `readAllLines` returns a `List`. What you may be saying is that the string may contain a number - in that case you can do a `try { Integer.parse(s); //here it's an integer } catch (Exception e) { //here it's not }`. – assylias Jul 25 '17 at 10:54
  • so your `myList` is of type `List` and you want to check whether comparing the strings with the given object (which must most probably be of type `String` too, as otherwise the cast wouldn't work out) is >= 0? did I miss something? did you omit a mapping from the type to `String`? What is the exact signature of your method? or do you really mean, that you put integers inside your `List` (which is possible, but not advisable)? – Roland Jul 25 '17 at 11:02

1 Answers1

1

In fact, my question was a possible duplicate of How do I define a method which takes a lambda as a parameter in Java 8?

and what I really wanted to do was

 public List<String> myFilter(MyComparator c){
        return myList
           .stream()
           .filter(c::compare)
           .collect(toList());
 }

with and interface MyComparator:

  public interface MyComparator{
        public boolean compare(String s);
  }

and then this could be called:

   List<String> myNewList=filter((String s)->s.compareTo(whateverString)>=0);

or even:

   List<String> myNewList=filter((String s)->{
           try{
               return Integer.compare(Integer.parseInt(s), 10)>=0;
           }catch(Exception e){
               return false;
           });
Myoch
  • 793
  • 1
  • 6
  • 24