programing

:: Java 8의 (이중 콜론) 연산자

goodcopy 2022. 7. 29. 23:00
반응형

:: Java 8의 (이중 콜론) 연산자

Java 8 소스를 탐색하던 중 이 코드의 특정 부분이 매우 놀라웠습니다.

//defined in IntPipeline.java
@Override
public final OptionalInt reduce(IntBinaryOperator op) {
    return evaluate(ReduceOps.makeInt(op));
}

@Override
public final OptionalInt max() {
    return reduce(Math::max); //this is the gotcha line
}

//defined in Math.java
public static int max(int a, int b) {
    return (a >= b) ? a : b;
}

이는?Math::max서드드 포인 ???인 「 」는 어떻게 되어 있습니까?static가 서서 to IntBinaryOperator

'아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.reduce를 사용한 방법Math.max(int, int)음음음같 뭇매하다

reduce(new IntBinaryOperator() {
    int applyAsInt(int left, int right) {
        return Math.max(left, right);
    }
});

하려면 , 「아까운」을 호출하는 만으로, 이 필요합니다.Math.max거기서 람다 표현이 나오죠.Java 8 이후로는 동일한 작업을 훨씬 짧은 시간 동안 수행할 수 있습니다.

reduce((int left, int right) -> Math.max(left, right));

게게어 ?떻 ?? ????컴파일러는 2개의 Java를 을 ".int 및 s를 1개 한다.는 1을 반환한다.intIntBinaryOperator('메서드')reduce★★★★★★★★★★★★★★★★★★★★★」이 구현하기를 것으로 합니다.고객이 실장하고 싶다고 가정했을 뿐입니다.IntBinaryOperator.

지.........Math.max(int, int)가 정식 하고 있다IntBinaryOperator직접 사용할 수 있습니다.할 수 결과만 할 수 메서드할 수 없습니다), 7은 Method Reference를 전달할 수 없습니다.::구문은 Java 8에서 메서드를 참조하기 위해 도입되었습니다.

reduce(Math::max);

이것은 실행 시 JVM이 아닌 컴파일러에 의해 해석됩니다.의 코드 다른 동일하기 는 3개의 코드 스니펫의더 효율적일 것입니다)으로할 수 .IntBinaryOperator★★★★★★★★★★★★★★★★★★!

('람다번역'도 참조)

::는 메서드 레퍼런스라고 불립니다.이는 기본적으로 단일 방법을 참조하는 것입니다. 즉, 기존 방법을 이름으로 참조합니다.

간단한 설명:
다음으로 스태틱 메서드에 대한 참조 예를 나타냅니다.

class Hey {
     public static double square(double num){
        return Math.pow(num, 2);
    }
}

Function<Double, Double> square = Hey::square;
double ans = square.apply(23d);

square오브젝트 참조와 마찬가지로 전달할 수 있으며 필요할 때 트리거할 수 있습니다.의 '할 수 .static예를 들어 다음과 같습니다.

class Hey {
    public double square(double num) {
        return Math.pow(num, 2);
    }
}

Hey hey = new Hey();
Function<Double, Double> square = hey::square;
double ans = square.apply(23d);

Function위는 기능하는 인터페이스입니다.완전히 이해하다::기능 인터페이스도 이해해 두는 것이 중요합니다.분명히 기능 인터페이스는 하나의 추상적인 방법을 가진 인터페이스입니다.

로는 examples능음음음음음음음음음음음음음음 examples examples examples가 있습니다.Runnable,Callable , , , , 입니다.ActionListener.

Function는, 「1」의 1개의 만을 가지는 입니다.apply하나의 논거로 결과를 낳는다.


<고객명>::s는 다음과 같습니다.

방법 참조는 람다 식(...)과 같은 처리를 하는 식이지만 방법 본문을 제공하는 대신 기존 방법을 이름으로 참조합니다.

예: 람다 본문을 쓰는 대신

Function<Double, Double> square = (Double x) -> x * x;

간단히 할 수 있다

Function<Double, Double> square = Hey::square;

시 의 '''는square메서드는 서로 완전히 동일하게 동작합니다. 같지 않을 수도 위의 내용을 하여 """로 합니다." "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "★★★★★★★★★★★★★★★★★★★★★★★·javap -c를 참조해 주세요.

충족해야 할 유일한 주요 기준은 제공하는 메서드가 오브젝트 참조로 사용하는 기능 인터페이스의 메서드와 유사한 시그니처를 가져야 한다는 것입니다.

다음은 불법입니다.

Supplier<Boolean> p = Hey::square; // illegal

square한다.double . 。get공급업체의 메서드가 값을 반환하지만 인수를 사용하지 않습니다.따라서 오류가 발생합니다.

메서드 레퍼런스란 기능 인터페이스의 메서드를 말합니다.(앞서 설명한 바와 같이 기능하는 인터페이스에는 각각1개의 방식밖에 설정할 수 없습니다).

외의로는, 「」를 참조해 주세요.acceptConsumer의 method는 입력을 받지만 아무것도 반환하지 않습니다.

Consumer<Integer> b1 = System::exit;   // void exit(int status)
Consumer<String[]> b2 = Arrays::sort;  // void sort(Object[] a)
Consumer<String> b3 = MyProgram::main; // void main(String... args)

class Hey {
    public double getRandom() {
        return Math.random();
    }
}

Callable<Double> call = hey::getRandom;
Supplier<Double> call2 = hey::getRandom;
DoubleSupplier sup = hey::getRandom;
// Supplier is functional interface that takes no argument and gives a result

에,,getRandom A를 합니다.double따라서 "인수 없이 반환" 기준을 충족하는 기능 인터페이스는 모두 사용할 수 있습니다.

또 다른 예는 다음과 같습니다.

Set<String> set = new HashSet<>();
set.addAll(Arrays.asList("leo","bale","hanks"));
Predicate<String> pred = set::contains;
boolean exists = pred.test("leo");

매개 변수화된 유형의 경우:

class Param<T> {
    T elem;
    public T get() {
        return elem;
    }

    public void set(T elem) {
        this.elem = elem;
    }

    public static <E> E returnSame(E elem) {
        return elem;
    }
}

Supplier<Param<Integer>> obj = Param<Integer>::new;
Param<Integer> param = obj.get();
Consumer<Integer> c = param::set;
Supplier<Integer> s = param::get;

Function<String, String> func = Param::<String>returnSame;

메서드 레퍼런스는 다른 스타일을 가질 수 있지만 기본적으로는 모두 같은 의미를 가지며 단순히 람다로 시각화할 수 있습니다.

  1. 방식 「」)ClassName::methName)
  2. 오브젝트의 (「」)instanceRef::methName)
  3. 의 슈퍼메서드()super::methName)
  4. 유형의 ( 「」 「」 「 」ClassName::methName)
  5. 레퍼런스(클래스 컨스트럭터 레퍼런스)ClassName::new)
  6. 레퍼런스(「」)TypeName[]::new)

자세한 내용은 http://cr.openjdk.java.net/~briangoetz/briangoetz/briangda/briangda-state-final.를 참조하십시오.

아, 아, 아, 아, 아, 아, 아, 아.::연산자는 메서드 참조에 사용됩니다.따라서 클래스에서 정적 메서드를 추출하거나 객체에서 메서드를 추출할 수 있습니다.생성자에 대해서도 동일한 연산자를 사용할 수 있습니다.여기에 언급된 모든 사례는 아래의 코드 샘플에 예시되어 있습니다.

Oracle의 공식 문서는 여기에서 찾을 수 있습니다.

문서에서는 JDK 8의 변경에 대해 자세히 설명합니다.Method/Constructor Reference 섹션에는 코드 예도 나와 있습니다.

interface ConstructorReference {
    T constructor();
}

interface  MethodReference {
   void anotherMethod(String input);
}

public class ConstructorClass {
    String value;

   public ConstructorClass() {
       value = "default";
   }

   public static void method(String input) {
      System.out.println(input);
   }

   public void nextMethod(String input) {
       // operations
   }

   public static void main(String... args) {
       // constructor reference
       ConstructorReference reference = ConstructorClass::new;
       ConstructorClass cc = reference.constructor();

       // static method reference
       MethodReference mr = cc::method;

       // object method reference
       MethodReference mr2 = cc::nextMethod;

       System.out.println(cc.value);
   }
}

조금 늦은 것 같지만 제 의견은 이렇습니다.람다 표현식은 익명 메서드를 만드는 데 사용됩니다.기존 메서드를 호출할 뿐이지만 메서드를 이름으로 직접 참조하는 것이 더 명확합니다.그리고 방법 참조는 방법 참조 연산자를 사용하여 그것을 가능하게 한다.::.

각 직원의 이름과 등급이 있는 다음과 같은 간단한 클래스를 고려해 보십시오.

public class Employee {
    private String name;
    private String grade;

    public Employee(String name, String grade) {
        this.name = name;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        this.grade = grade;
    }
}

어떤 방법으로든 반환된 직원 목록이 있고 해당 직원을 등급별로 분류하려고 합니다.익명의 클래스를 다음과 같이 사용할 수 있습니다.

    List<Employee> employeeList = getDummyEmployees();

    // Using anonymous class
    employeeList.sort(new Comparator<Employee>() {
           @Override
           public int compare(Employee e1, Employee e2) {
               return e1.getGrade().compareTo(e2.getGrade());
           }
    });

get Dummy Emploe()는 다음과 같은 메서드입니다.

private static List<Employee> getDummyEmployees() {
        return Arrays.asList(new Employee("Carrie", "C"),
                new Employee("Fanishwar", "F"),
                new Employee("Brian", "B"),
                new Employee("Donald", "D"),
                new Employee("Adam", "A"),
                new Employee("Evan", "E")
                );
    }

Comparator는 기능 인터페이스입니다.기능 인터페이스란 추상적인 메서드를 1개만 사용하는 인터페이스입니다(단, 1개 이상의 기본 메서드 또는 스태틱메서드를 포함할 수 있습니다).Lambda 표현식은 다음을 구현합니다.@FunctionalInterface따라서 기능 인터페이스는 추상적인 방법을 하나만 가질 수 있습니다.람다 식을 다음과 같이 사용할 수 있습니다.

employeeList.sort((e1,e2) -> e1.getGrade().compareTo(e2.getGrade())); // lambda exp

다 좋은 것 같은데 만약에 수업이Employee는음

public class Employee {
    private String name;
    private String grade;
    // getter and setter
    public static int compareByGrade(Employee e1, Employee e2) {
        return e1.grade.compareTo(e2.grade);
    }
}

이 경우 메서드 이름 자체를 사용하는 것이 더 명확해집니다.따라서 방법 참조를 사용하여 다음과 같이 방법을 직접 참조할 수 있습니다.

employeeList.sort(Employee::compareByGrade); // method reference

문서에 따르면 메서드 참조에는 다음 4종류가 있습니다.

+----+-------------------------------------------------------+--------------------------------------+
|    | Kind                                                  | Example                              |
+----+-------------------------------------------------------+--------------------------------------+
| 1  | Reference to a static method                          | ContainingClass::staticMethodName    |
+----+-------------------------------------------------------+--------------------------------------+
| 2  |Reference to an instance method of a particular object | containingObject::instanceMethodName | 
+----+-------------------------------------------------------+--------------------------------------+
| 3  | Reference to an instance method of an arbitrary object| ContainingType::methodName           |
|    | of a particular type                                  |                                      |  
+----+-------------------------------------------------------+--------------------------------------+
| 4  |Reference to a constructor                             | ClassName::new                       |
+------------------------------------------------------------+--------------------------------------+

::는 Java 8에 포함된 새로운 연산자로 기존 클래스의 메서드를 참조하기 위해 사용됩니다.클래스의 스태틱 메서드 및 비 스태틱 메서드를 참조할 수 있습니다.

스태틱 메서드를 참조하는 경우 구문은 다음과 같습니다.

ClassName :: methodName 

비정적 메서드를 참조할 경우 구문은 다음과 같습니다.

objRef :: methodName

그리고.

ClassName :: methodName

메서드를 참조하기 위한 유일한 전제조건은 메서드가 기능 인터페이스에 존재하며 메서드 참조와 호환되어야 한다는 것입니다.

메서드 참조는 평가 시 기능 인터페이스의 인스턴스를 만듭니다.

검색처: http://www.speakingcs.com/2014/08/method-references-in-java-8.html

이것은 Java 8의 메서드레퍼런스입니다Oracle 문서는 여기에 있습니다.

설명서에 기재되어 있는 바와 같이...

메서드는 Person::compareBy를 참조합니다.에이징은 정적 메서드에 대한 참조입니다.

다음으로 특정 객체의 인스턴스 메서드에 대한 참조 예를 나타냅니다.

class ComparisonProvider {
    public int compareByName(Person a, Person b) {
        return a.getName().compareTo(b.getName());
    }

    public int compareByAge(Person a, Person b) {
        return a.getBirthday().compareTo(b.getBirthday());
    }
}

ComparisonProvider myComparisonProvider = new ComparisonProvider();
Arrays.sort(rosterAsArray, myComparisonProvider::compareByName); 

메서드 참조 myComparisonProvider::compareByName은 myComparisonProvider 객체의 일부인 메서드 comparisonProvider를 호출합니다.JRE는 메서드유형 인수를 유추합니다.이 경우 (Person, Person)입니다.

:: 메서드 참조용으로 Java 8에서 연산자가 도입되었습니다.메서드 참조는 하나의 메서드만 실행하는 람다 표현식의 줄임말 구문입니다.메서드 참조의 일반적인 구문은 다음과 같습니다.

Object :: methodName

익명 클래스를 사용하는 대신 람다 식을 사용할 수 있습니다.그러나 때때로 람다 표현은 다음과 같은 몇 가지 메서드에 대한 호출에 불과합니다.

Consumer<String> c = s -> System.out.println(s);

코드를 명확하게 하기 위해 람다 식을 메서드 참조로 변환할 수 있습니다.

Consumer<String> c = System.out::println;

솔직히 너무 복잡한 답변들이 많이 있는데 그건 절제된 표현입니다.

답은 매우 간단합니다. :: Method References https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html 라고 합니다.

복사 붙여넣기는 하지 않습니다.링크에서 모든 정보를 찾을 수 있습니다.테이블까지 스크롤하면 됩니다.


이제 메서드 레퍼런스가 무엇인지 간단히 살펴보겠습니다.

A::b인라인 람다 식(패럴...) -> A.b(패럴...)를 약간 대체합니다.

이를 질문과 연관지으려면 Java lambda 표현을 이해해야 합니다.어렵지 않아요.

인라인 람다 표현은 정의된 기능 인터페이스(1개 이상의 메서드가 없는 인터페이스)와 비슷합니다.무슨 뜻인지 간단히 살펴보겠습니다.

InterfaceX f = (x) -> x*x; 

InterfaceX는 기능하는 인터페이스여야 합니다.컴파일러의 인터페이스 X에서 중요한 것은 다음과 같은 포맷을 정의하는 것입니다.

InterfaceX는 다음 중 하나입니다.

interface InterfaceX
{
    public Integer callMe(Integer x);
}

또는 이것

interface InterfaceX
{
    public Double callMe(Integer x);
}

또는 그 이상의 범용:

interface InterfaceX<T,U>
{
    public T callMe(U x);
}

앞에서 정의한 첫 번째 케이스와 인라인 람다 식을 살펴보겠습니다.

Java 8 이전에는 다음과 같이 정의할 수 있었습니다.

 InterfaceX o = new InterfaceX(){
                     public int callMe (int x) 
                       {
                        return x*x;
                       } };
                     

기능적으로는 같은 것입니다.차이점은 컴파일러가 이를 어떻게 인식하느냐에 있습니다.

이제 인라인 람다 식을 살펴보았으므로 메서드 참조(::)로 돌아가겠습니다.예를 들어 다음과 같은 클래스가 있다고 가정해 보겠습니다.

class Q {
        public static int anyFunction(int x)
             {
                 return x+5;
             } 
        }
    

method anyFunctions는 InterfaceX callMe와 같은 타입이므로 Method Reference와 동등하게 할 수 있습니다.

다음과 같이 쓸 수 있습니다.

InterfaceX o =  Q::anyFunction; 

이는 다음과 같습니다.

InterfaceX o = (x) -> Q.anyFunction(x);

메서드 참조의 장점은 처음에는 변수를 할당할 때까지 유형이 없다는 것입니다.따라서 파라미터로서 동등한 외관(정의된 타입이 있는) 기능 인터페이스에 전달할 수 있습니다.그게 바로 당신 사건에서 일어나는 일입니다.

Java에서는 메서드 참조 연산자로도 알려진 이중 콜론(:) 연산자는 클래스의 도움을 받아 메서드를 직접 참조함으로써 메서드를 호출하는 데 사용됩니다.람다 식과 똑같이 동작합니다.람다 식과 유일하게 다른 점은 메서드에 대한 위임자를 제공하는 대신 이름으로 메서드에 대한 직접 참조를 사용한다는 것입니다.

구문:

<Class name>::<method name>

이 기호는 Lamda 식 대신 사용할 수 있습니다.

프로그램:

// Java code to print the elements of Stream
// without using double colon operator
  
import java.util.stream.*;
  
class MyClass {
    public static void main(String[] args)
    {
  
        // Get the stream
        Stream<String> stream
            = Stream.of("Testing","Program");
  
        // Print the stream
        stream.forEach(s -> System.out.println(s));
    }
}

출력:

Testing
Program

★★stream.forEach(s -> System.out.println(s)); 가능 ★★★

stream.forEach(System.out::println);

또한 첫 번째 방법은 프로그래밍 중에 가장 많이 사용됩니다.

:: 는 메서드 참조라고 불립니다.calculatePrice 메서드를 purchase 클래스의 calculatePrice 메서드라고 합니다.다음으로 다음과 같이 쓸 수 있습니다.

Purchase::calculatePrice

방법 참조가 람다 식으로 변환되기 때문에 람다 식을 쓰는 짧은 형식으로도 볼 수 있습니다.

나는 이 소스가 매우 흥미롭다고 생각했다.

사실, 이중 콜론으로 변하는 것은 람다입니다.Double Colon이 더 잘 읽힙니다.다음의 순서에 따릅니다.

순서 1:

// We create a comparator of two persons
Comparator c = (Person p1, Person p2) -> p1.getAge().compareTo(p2.getAge());

순서 2:

// We use the interference
Comparator c = (p1, p2) -> p1.getAge().compareTo(p2.getAge());

순서 3:

// The magic using method reference
Comparator c = Comparator.comparing(Person::getAge);

return reduce(Math::max);동등하지 않다return reduce(max());

하지만 그 말은, 다음과 같은 거지

IntBinaryOperator myLambda = (a, b)->{(a >= b) ? a : b};//56 keystrokes I had to type -_-
return reduce(myLambda);

이렇게 쓰면 47개의 키 입력을 저장할 수 있습니다.

return reduce(Math::max);//Only 9 keystrokes ^_^

에서는 많은 이 잘 되어 있기 ::행동, 추가적으로 나는 그것을 명확히 하고 싶다.:: instance 변수에 사용되는 경우 연산자는 참조하는 기능 인터페이스와 완전히 동일한 시그니처를 가질 필요가 없습니다.TestObject 유형을 가진 BinaryOperator가 필요하다고 가정합니다.기존 방식으로는 다음과 같이 구현되었습니다.

BinaryOperator<TestObject> binary = new BinaryOperator<TestObject>() {

        @Override
        public TestObject apply(TestObject t, TestObject u) {

            return t;
        }
    };

TestObject 2의 TestObject가 TestObject가 됩니다.를 하여 이 ::연산자는 정적 방법으로 시작할 수 있습니다.

public class TestObject {


    public static final TestObject testStatic(TestObject t, TestObject t2){
        return t;
    }
}

그리고 나서 전화:

BinaryOperator<TestObject> binary = TestObject::testStatic;

네, 잘 컴파일 되었습니다.인스턴스 방식이 필요한 경우에는 어떻게 해야 합니까?인스턴스 메서드를 사용하여 Test Object를 업데이트합니다.

public class TestObject {

    public final TestObject testInstance(TestObject t, TestObject t2){
        return t;
    }

    public static final TestObject testStatic(TestObject t, TestObject t2){
        return t;
    }
}

이제 다음과 같이 인스턴스에 액세스할 수 있습니다.

TestObject testObject = new TestObject();
BinaryOperator<TestObject> binary = testObject::testInstance;

이 코드는 정상적으로 컴파일되지만 다음 코드는 그렇지 않습니다.

BinaryOperator<TestObject> binary = TestObject::testInstance;

이클립스에서는 TestObject 유형에서 비정적 메서드 testInstance(TestObject, TestObject)를 스태틱하게 참조할 수 없습니다."

공평한이지만, 오버로드가 testInstance음음음같 뭇매하다

public class TestObject {

    public final TestObject testInstance(TestObject t){
        return t;
    }

    public final TestObject testInstance(TestObject t, TestObject t2){
        return t;
    }

    public static final TestObject testStatic(TestObject t, TestObject t2){
        return t;
    }
}

전화:

BinaryOperator<TestObject> binary = TestObject::testInstance;

코드는 정상적으로 컴파일 됩니다.「 」를 .testInstance더블 파라미터가 아닌 싱글 파라미터로 설정합니다.그럼 두지 라라 라라 라? ???츠키다

public class TestObject {

    public TestObject() {
        System.out.println(this.hashCode());
    }

    public final TestObject testInstance(TestObject t){
        System.out.println("Test instance called. this.hashCode:" 
    + this.hashCode());
        System.out.println("Given parameter hashCode:" + t.hashCode());
        return t;
    }

    public final TestObject testInstance(TestObject t, TestObject t2){
        return t;
    }

    public static final TestObject testStatic(TestObject t, TestObject t2){
        return t;
    }
}

출력:

 1418481495  
 303563356  
 Test instance called. this.hashCode:1418481495
 Given parameter hashCode:303563356

JVM param1.testInstance(param2)의 설정. ''는 쓸 수 요?testInstanceTest Object test 른른 、 [ Test Object 。

public class TestUtil {

    public final TestObject testInstance(TestObject t){
        return t;
    }
}

전화:

BinaryOperator<TestObject> binary = TestUtil::testInstance;

컴파일은 이루어지지 않고 컴파일러는 "TestUtil 유형은 testInstance(TestObject, TestObject)를 정의하지 않습니다."라고 말합니다.따라서 컴파일러는 동일한 유형이 아닌 경우 정적 참조를 찾습니다.그럼 다형성은요?최종 수식자를 삭제하고 SubTestObject 클래스를 추가하는 경우:

public class SubTestObject extends TestObject {

    public final TestObject testInstance(TestObject t){
        return t;
    }

}

전화:

BinaryOperator<TestObject> binary = SubTestObject::testInstance;

컴파일러도 컴파일 할 수 없지만 정적 참조를 계속 찾습니다.단, 아래 코드는 정상적으로 컴파일 됩니다.테스트에 합격하고 있기 때문입니다.

public class TestObject {

    public SubTestObject testInstance(Object t){
        return (SubTestObject) t;
    }

}

BinaryOperator<TestObject> binary = TestObject::testInstance;

*공부중이기때문에잘못된것같으면수정해주세요

java-8에서 단순작업의 Streams Reducer는 2개의 값을 입력으로 하여 계산 후 결과를 반환하는 함수입니다.이 결과는 다음 반복에서 제공됩니다.

Math:max 함수의 경우, 메서드는 전달된 두 값의 최대값을 계속 반환하고 결국 가장 큰 값을 얻게 됩니다.

이전 Java 버전에서는 "::" 또는 "lamd" 대신 다음을 사용할 수 있습니다.

public interface Action {
    void execute();
}

public class ActionImpl implements Action {

    @Override
    public void execute() {
        System.out.println("execute with ActionImpl");
    }

}

public static void main(String[] args) {
    Action action = new Action() {
        @Override
        public void execute() {
            System.out.println("execute with anonymous class");
        }
    };
    action.execute();

    //or

    Action actionImpl = new ActionImpl();
    actionImpl.execute();
}

또는 다음 방법으로 전달합니다.

public static void doSomething(Action action) {
    action.execute();
}

실행 시 동작은 동일합니다.바이트 코드가 같을 수도 있고 같지 않을 수도 있습니다(위 Incase의 경우 동일한 바이트 코드를 생성합니다(위 사항을 준수하고 javaap -c; 확인).

실행 시 동작은 동일합니다.method(math::max);는 동일한 계산을 생성합니다(위 사항을 준수하고 javap -c;를 체크합니다).

입니다.::메서드 레퍼런스는 이 기능을 합니다.요약하면 메서드(또는 생성자)를 실행하지 않고 참조할 수 있는 방법을 제공하고, 평가될 때 대상 유형 컨텍스트를 제공하는 기능 인터페이스의 인스턴스를 생성합니다.

두이 ᄃ자 안에 있는 입니다.ArrayList (하지 ):: 의 코멘트에 기재되어 .설명은 아래 코멘트에 있습니다.


「 」를 하지 않는 ::

import java.util.*;

class MyClass {
    private int val;
    MyClass (int v) { val = v; }
    int getVal() { return val; }
}

class ByVal implements Comparator<MyClass> {
    // no need to create this class when using method reference
    public int compare(MyClass source, MyClass ref) {
        return source.getVal() - ref.getVal();
    }
}

public class FindMaxInCol {
    public static void main(String args[]) {
        ArrayList<MyClass> myClassList = new ArrayList<MyClass>();
        myClassList.add(new MyClass(1));
        myClassList.add(new MyClass(0));
        myClassList.add(new MyClass(3));
        myClassList.add(new MyClass(6));

        MyClass maxValObj = Collections.max(myClassList, new ByVal());
    }
}

「 」를 .::

import java.util.*;

class MyClass {
    private int val;
    MyClass (int v) { val = v; }
    int getVal() { return val; }
}

public class FindMaxInCol {
    static int compareMyClass(MyClass source, MyClass ref) {
        // This static method is compatible with the compare() method defined by Comparator. 
        // So there's no need to explicitly implement and create an instance of Comparator like the first example.
        return source.getVal() - ref.getVal();
    }

    public static void main(String args[]) {
        ArrayList<MyClass> myClassList = new ArrayList<MyClass>();
        myClassList.add(new MyClass(1));
        myClassList.add(new MyClass(0));
        myClassList.add(new MyClass(3));
        myClassList.add(new MyClass(6));

        MyClass maxValObj = Collections.max(myClassList, FindMaxInCol::compareMyClass);
    }
}

★★★★★★★★★★★★★★★ 。::연산자는 Java 8에서 메서드 참조로 도입되었습니다.방법 참조는 기존 방법을 이름으로 참조하는 데 사용되는 람다 식의 한 형식입니다.

클래스명: methodName

예:-

  • stream.forEach(element -> System.out.println(element))

Colon Double Colon ::

  • stream.forEach(System.out::println(element))

언급URL : https://stackoverflow.com/questions/20001427/double-colon-operator-in-java-8

반응형