2

I'm trying to sort an arrayList of methods reflection , but I don't know how to declare the compare function.

I added an annotation on each of my methods but when I call Collections.sort() it tells me that

Error:(222, 16) java: no suitable method found for sort(java.util.List<java.lang.reflect.Method>)
    method java.util.Collections.<T>sort(java.util.List<T>) is not applicable
      (inferred type does not conform to upper bound(s)
        inferred: java.lang.reflect.Method
        upper bound(s): java.lang.Comparable<? super java.lang.reflect.Method>)
    method java.util.Collections.<T>sort(java.util.List<T>,java.util.Comparator<? super T>) is not applicable
      (cannot infer type-variable(s) T
        (actual and formal argument lists differ in length))

Here is my code :

RecommendationForm.java

public class test {

  @SortedMethod(3)
  public String[] getIssueRef() {
    return issueRef;
  }

  @SortedMethod(2)
  public String[] getAudRef() {
    return audRef;
  }

  @SortedMethod(1)
  public String[] getCradat() {
    return cradat;
  }


  @SortedMethod(4)
  public String[] getPriority() {
    return priority;
  }

  @SortedMethod(5)
  public String[] getStatus() {
    return status;
  }

}

SortedMethod.java:

public @interface SortedMethod{

  int value();



}

And my Function :

Method methods[] = ReflectionUtils.getAllDeclaredMethods(RecommendationForm.class);

    List<Method> getters = new ArrayList<Method>();

    for (int i = 0; i < methods.length; i++) {
      if ((methods[i].getName().startsWith("get")) && !(methods[i].getName().equals("getClass"))) {
        getters.add(methods[i]);
        //System.out.println(methods[i].toString());
      }
    }
    Collections.sort(getters);

Thank You !

I've solved my problem by adding a comparator method :

Collections.sort(getters, new Comparator<Method>() {
      @Override
      public int compare(Method o1, Method o2) {
        if(o1.getAnnotation(SortedMethod.class).value() > o2.getAnnotation(SortedMethod.class).value()){
          return 1;
        }
        else{
          return -1;
        }
      }
    });
  • 1
    Try using a comparator https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html – Hongyu Wang Jul 16 '18 at 15:34
  • Possible duplicate of [Sort ArrayList of custom Objects by property](https://stackoverflow.com/questions/2784514/sort-arraylist-of-custom-objects-by-property) – Hongyu Wang Jul 16 '18 at 15:35
  • I guess you want to sort by the `value` field of the annotation? – Jorn Vernee Jul 16 '18 at 15:54
  • Yes I want to sort by the value of the annotation – Giovanni Raziq Jul 16 '18 at 19:44
  • What import statements/packages do I need to get the "@SortedMethod" annotation to work? I see at the bottom of this page that someone is suggesting custom annotations. Is that what people are using here? – Crislips Apr 13 '21 at 19:38

2 Answers2

3

You need to add the RUNTIME rentention policy to your annotation, otherwise it gets removed after compilation:

@Retention(RetentionPolicy.RUNTIME)
@interface SortedMethod {
    int value();
}

Then you can sort by comparing the value field of the annotation e.g.:

List<Method> sorted = Arrays.stream(Test.class.getDeclaredMethods())
    .filter(m -> m.getAnnotation(SortedMethod.class) != null) // only use annotated methods
    .sorted(Comparator.comparingInt(m -> m.getAnnotation(SortedMethod.class).value())) // sort by value
    .collect(Collectors.toList());

System.out.println(sorted);
Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
2

You must put a comparator in your Collections.sort, so the sort method knows on which criteria your methods must be sort. Put your reflexion code in this comparator.

Collections.sort(getters, new Comparator<Method>() {
        @Override
        public int compare(Method o1, Method o2) {
            // your code
        }
    });
Oreste Viron
  • 3,592
  • 3
  • 22
  • 34