Home  >  Q&A  >  body text

java - this in anonymous inner class, how to get in lambda?

nsv_productdetail.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int bottomMargin = ((ViewGroup.MarginLayoutParams) nsv_productdetail.getLayoutParams()).bottomMargin;
                nsv_productdetail.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });

If the above code is converted into lambda, this will point to the external class, and the listener cannot be removed at this time.
So I would like to ask, how can an anonymous inner class (an anonymous inner class that can be converted to a lambda) obtain itself in the lambda?

阿神阿神2675 days ago1065

reply all(2)I'll reply

  • PHP中文网

    PHP中文网2017-06-23 09:15:26

    Replace some anonymous inner classes
    This section will introduce how to use Lambda expressions to simplify the writing of anonymous inner classes. However, Lambda expressions cannot replace all anonymous inner classes. They can only be used to replace the abbreviation of Functional Interface. . Don’t worry about the details yet, let’s look at a few examples.

    Example 1: Abbreviation of parameterless function
    If you need to create a new thread, a common way of writing it is like this:

    // JDK7 anonymous inner class writing method
    new Thread(new Runnable(){// interface name

    @Override
    public void run(){// 方法名
        System.out.println("Thread run()");
    }

    }).start();
    The above code passes an anonymous Runnable object to the Tread class, and overloads the run() method of the Runnable interface to implement the corresponding logic. This is a common way of writing in JDK7 and before. Anonymous inner classes save you the trouble of naming the class, but it is still not simple enough. In Java 8, it can be simplified to the following form:

    // How to write JDK8 Lambda expression
    new Thread(

        () -> System.out.println("Thread run()")// 省略接口名和方法名

    ).start();
    The above code has the same function as the anonymous inner class, but it goes further than the anonymous inner class. Here the connection port name and function name are omitted together, making it more refreshing to write. If the function body has multiple lines, it can be enclosed in curly braces, like this:

    // How to write JDK8 Lambda expression code block
    new Thread(

        () -> {
            System.out.print("Hello");
            System.out.println(" Hoolee");
        }

    ).start();
    Example 2: Abbreviation of function with parameters
    If you want to pass a custom comparator to a string list and sort it according to the string length, the writing form of Java 7 is as follows:

    // How to write anonymous inner classes in JDK7
    List<String> list = Arrays.asList("I", "love", "you", "too");
    Collections.sort(list, new Comparator<String>() {//Interface name

    @Override
    public int compare(String s1, String s2){// 方法名
        if(s1 == null)
            return -1;
        if(s2 == null)
            return 1;
        return s1.length()-s2.length();
    }

    });
    The above code overloads the compare() method of the Comparator interface through the internal class to implement comparison logic. Using Lambda expression can be abbreviated as follows:

    // How to write JDK8 Lambda expression
    List<String> list = Arrays.asList("I", "love", "you", "too");
    Collections.sort(list, (s1, s2) -> ;{// Omit the type of parameter table

    if(s1 == null)
        return -1;
    if(s2 == null)
        return 1;
    return s1.length()-s2.length();

    });
    The above code has the same function as the anonymous inner class. In addition to omitting the interface name and method name, the type of the parameter table is also omitted in the code. This is due to javac's type inference mechanism. The compiler can infer the parameter type based on contextual information. Of course, there are also times when the inference fails, in which case the parameter type needs to be specified manually. Note that Java is a strongly typed language, and each variable and object must have a clear type.

    The basis for the abbreviation
    Maybe you have already thought that the basis for using Lambda is that there must be a corresponding functional interface (a functional interface refers to an interface with only one abstract method inside). This is consistent with Java being a strongly typed language, which means that you cannot write Lambda expressions arbitrarily anywhere in the code. In fact, the type of Lambda is the type corresponding to the function interface. Another basis for lambda expressions is the type inference mechanism. If the context information is sufficient, the compiler can infer the type of the parameter table without explicitly naming it. Lambda expresses more legal written forms as follows:

    // Written form of Lambda expression
    Runnable run = () -> System.out.println("Hello World");// 1
    ActionListener listener = event -> System.out.println("button clicked ");// 2
    Runnable multiLine = () -> {// 3 code blocks

    System.out.print("Hello");
    System.out.println(" Hoolee");

    };
    BinaryOperator<Long> add = (Long x, Long y) -> x + y;// 4
    BinaryOperator<Long> addImplicit = (x, y) -> Inference
    In the above code, 1 shows the abbreviation of the parameterless function; 2 shows the abbreviation of the parameterized function and the type inference mechanism; 3 is the writing method of the code block; 4 and 5 show the type inference mechanism again.

    Custom function interface
    Custom function interface is easy, you only need to write an interface with only one abstract method.

    // Custom function interface
    @FunctionalInterface
    public interface ConsumerInterface<T>{

    void accept(T t);

    }
    @FunctionalInterface in the above code is optional, but adding this annotation the compiler will help you check whether the interface complies with the functional interface specification. Just like adding the @Override annotation will check whether the function is overloaded.

    With the above interface definition, you can write code similar to the following:

    ConsumerInterface<String> consumer = str -> System.out.println(str);

    Further, you can also use it like this:

    class MyStream<T>{

    private List<T> list;
    ...
    public void myForEach(ConsumerInterface<T> consumer){// 1
        for(T t : list){
            consumer.accept(t);
        }
    }

    }
    MyStream<String> stream = new MyStream<String>();
    stream.myForEach(str -> System.out.println(str));// Use custom function interface to write Lambda expression

    reply
    0
  • 女神的闺蜜爱上我

    女神的闺蜜爱上我2017-06-23 09:15:26

    What you can’t do is that Lambda itself is not an object.

    reply
    0
  • Cancelreply