java 기본 12 (lambda 표현식)

10360 단어

java 기본 12 (lambda 표현식)


1 lambda 표현식이 무엇입니까


lambda 표현식은 익명 함수로 한 함수를 다른 함수의 매개 변수로 하고 함수를 매개 변수로 전달할 수 있습니다. (전달된 코드로 이해할 수 있습니다.)

2 왜 lambda 표현식을 사용합니까


lambda 표현식은 더욱 간결하고 유연한 코드를 쓸 수 있다.다음 코드를 먼저 볼게요.
public class TestLambda {
	//       
	@Test
	public void test() {
		TreeSet set = new TreeSet<>(new Comparator() {
			@Override
			public int compare(Integer o1, Integer o2) {			
				return Integer.compare(o1, o2);
			}		
		});
	}
	//lambda  
	@Test
	public void test1() {
		Comparator com = (x,y)->Integer.compare(x, y);
		TreeSet set = new TreeSet<>(com);		
	}
    List list = Arrays.asList(new Person("  ", 18, 5000.0), new Person("  ", 21, 6000.0),new Person("  ", 25, 7000.0));

	//           20  
	@Test
	public void test2() {
		for (Person person : list) {
			if(person.getAge()>20) {
				System.out.println(person);
			}
		}
	}

	// lambda        20  
	@Test
	public void test3() {
		list.stream()
		.filter((x)-> x.getAge()>20)
		.forEach(System.out::println);
	}
}

 

3 lambda 문법


자바8에 '->' 조작부호를 도입했습니다. 화살표 조작부호나 lambda 조작부호라고 하는데, lambda는 익명 함수를 대체하는 데 사용됩니다.
lambda 표현식을 사용하는 전제: 인터페이스 (함수식 인터페이스) 에는 추상적인 방법만 있을 수 있습니다.
함수식 인터페이스: 인터페이스에 추상적인 방법만 있는 인터페이스입니다. 주석 @Functioninterface로 한정합니다
lambda 연산자는 lambda 표현식을 두 부분으로 분할합니다.
(1) 왼쪽은 lambda 표현식의 매개 변수 목록(추상적인 방법으로 이해할 수 있는 매개 변수)
(2) 오른쪽은 lambda 표현식에서 실행해야 하는 기능, 즉 lambda체(추상적인 방법으로 이해할 수 있는 기능)
3.1 형식 1: 매개 변수 없음, 반환 값 없음
()->System.out.println("Hello Lambda!");
3.2 포맷2: 하나의 매개 변수가 있고 반환값이 없음(매개 변수만 생략할 수 있는 경우(), 하나의 문법만 생략할 수 있는 경우{})
(x)->System.out.println(x);
3.3 형식 3: 매개 변수가 하나일 경우 괄호는 생략하고 쓰지 않을 수 있다
x -> System.out.println(x);
3.4 포맷4: 두 개 이상의 매개 변수가 있고 되돌아오는 값이 있으며 Lambda체에 여러 개의 문이 있다
Comparator com = (x, y) -> {
          System.out.println ("함수식 인터페이스");
           return Integer.compare(x, y);
};
3.5 형식 5: 만약 Lambda체에 문장이 하나만 있다면,return과 괄호는 모두 생략하고 쓰지 않을 수 있다
Comparator com = (x, y) -> Integer.compare(x, y);
3.6 형식 6: Lambda 표현식의 매개 변수 목록의 데이터 형식은 생략하고 쓰지 않을 수 있다. 왜냐하면 JVM 컴파일러가 상하문을 통해 데이터 형식, 즉'유형 추정'을 추정하기 때문이다.
(Integer x, Integer y) -> Integer.compare(x, y);
 

4 내장된 4개의 핵심 함수식 인터페이스


4.1 소비자용 커넥터 Consumer


추상적인 방법: void accept(T t);
    //     
	@Test
	public void test1() {
    //	Consumer con = (x)-> System.out.print(x);
   	//	consumer(100, con);
		consumer(100,(x)-> System.out.print(x));
	}
	public void consumer(double money,Consumer con){
		con.accept(money);
	}

4.2 공급형 인터페이스 Supplier


추상적인 방법: T get();
	//     
	@Test
	public void test2() {
		List randomNum = getRandomNum(10,()->new Random().nextInt(100));
		System.out.println(randomNum);
	}
	/**
	 * @Description           
	 * @param count
	 * @param su
	 * @return int
	 */
	public List getRandomNum(int count,Supplier su) {
		List list = new ArrayList<>();
		for(int i = 0;i

4.3 함수 인터페이스 Function


추상적인 방법: R apply(T t);
	//      
	@Test
	public void test3() {
	
		List list = toUpperList(new ArrayList(Arrays.asList("abc","df","aa","cc")),
				(x)-> x.toUpperCase()
				);
		System.out.println(list);
	}
	/**
	 * @Description             
	 * @param list
	 * @param fun
	 * @return List
	 */
	public List toUpperList(List list,Function fun){
		for(int i = 0;i < list.size();i++) {
			String apply = fun.apply(list.get(i));
			list.set(i, apply);
		}	
		return list;	
	}

4.4 단언형 인터페이스Predicate


추상적인 방법: boolean test(T t),
//     
	@Test
	public void test4() {
		List list = Remove(new ArrayList(Arrays.asList("abc","df","aa","cc")),
				(s) -> s.length() < 2);
		System.out.println(list);
	}
	/**
	 * @Description          2   
	 * @param list
	 * @param pre
	 * @return List
	 */
	public List Remove(List list,Predicate pre) {
		Iterator it = list.iterator();
		while(it.hasNext()) {
			String str = it.next();
			if(pre.test(str)) {
				list.remove(str);
			}
		}
		return list;
		
	}

5 메소드 참조


5.1 방법 참조


Lambda체의 기능을 기존의 방법과 방법으로 제공하여 방법 인용을 사용할 수 있다(방법 인용은 Lambda의 또 다른 표현 형식으로 이해할 수 있다)
메서드 참조 분류:
(1) 대상의 인용::실례 방법명
    //     ::     
	@Test
	public void test1() {
		Date date = new Date();
		//  lambda   
		Supplier su = ()-> date.getTime();
		System.out.println(su.get());
		//    
		Supplier su1 = date::getTime;
		System.out.println(su1.get());
	}

(2) 클래스 이름: 정적 방법 이름
    //  ::     
	@Test
	public void test2() {
		Comparator com = (x,y)-> Integer.compare(x, y);
		System.out.println(com.compare(4, 5));
		
		Comparator com1 = Integer::compare;
		System.out.println(com1.compare(4, 5));
	}

(3) 클래스 이름::인스턴스 메서드 이름
    //  ::     
	@Test
	public void test3() {
		Function fun = (x)-> x.show();
		System.out.println(fun.apply(new Person()));
		
		Function fun1 = Person::show;
		System.out.println(fun.apply(new Person()));
	}
	class Person{
		public String show() {
			return "aaa";
		}
	}

주의: 방법은 인용된 매개 변수 목록과 반환값 형식을 인용하고 함수식 인터페이스에서 추상적인 방법의 매개 변수 목록과 반환값 형식과 일치해야 합니다.Lambda의 매개변수 목록의 첫 번째 매개변수가 인스턴스 메소드 호출이고 두 번째 매개변수(또는 참조되지 않음)가 인스턴스 메소드의 매개변수인 경우 형식: ClassName::MethodName

5.2 구조기 참조


구조기의 매개 변수 목록은 함수식의 매개 변수 목록과 일치해야 한다
클래스 이름::new
    //   :: new
	@Test
	public void test4() {
		Supplier sup = () -> new Person();
		System.out.println(sup.get());
				
		Supplier sup2 = Person::new;
		System.out.println(sup2.get());
	}

 

6 Stream


6.1 Stream이란?


Stream 흐름은 데이터 소스(컬렉션, 배열)를 조작하는 데 사용되는 요소 시퀀스입니다.
Stream은 집합 요소가 아닙니다. 데이터 구조가 아니라 데이터를 저장하지 않습니다. 알고리즘과 계산에 관한 것입니다. 고급 버전의 Iterator와 같습니다.원시 버전의 Iterator는 원소를 하나하나 뚜렷하게 옮겨다니며 일부 조작을 수행할 수 있다.고급 버전의 Stream은 요소에 대해 어떤 조작을 해야 하는지, 예를 들어'10보다 긴 문자열을 필터하기'등이다. Stream은 내부를 은밀하게 훑어보고 해당하는 데이터 변환을 한다.Stream은 일방적인 데이터로 한 번만 반복할 수 있습니다.교체기는 또 다른 것은Stream은 병렬화 작업을 할 수 있고 교체기는 명령식, 직렬화 작업만 할 수 있다.
주의: ① stream 자체는 요소를 저장하지 않습니다.② stream은 대상을 바꾸지 않고 새로운stream으로 돌아간다.③ stream 작업은 지연됩니다.

6.2 Stream 작업


작업 단계: ① Stream 만들기;② 중간 조작;③ 작업 종료
(1) 흐름 생성
    @Test
	public void test1() {
		//1.Collection   ,        
		List list = new ArrayList<>();
		Stream stream = list.stream();
		
		//2.  Arrays  stream       
		String[] arr = new String[5];
		Stream stream2 = Arrays.stream(arr);
		
		//3.  Stream       of
		Stream of = Stream.of(11,22,33,44,55);
		
		//4.     
		Stream limit = Stream.iterate(0, (x)-> x + 1).limit(20);
		limit.forEach(System.out::println);
		
		//5. Stream generate  
		Stream limit2 = Stream.generate(Math::random).limit(20);
		limit2.forEach(System.out::println);
	}

(2) 중간 작업:
일반적인 중간 작업 방법은 다음과 같습니다.
메서드
묘사
Stream filter(Predicate super T> predicate)
Lambda 수신, 흐름에서 일부 요소 제외
Stream limit(long maxSize)
흐름을 차단하여 원소가 주어진 수량을 초과하지 않도록 하다
Stream skip(long n) 
원소를 건너뛰고 이전 n개의 원소를 버린 흐름을 되돌려줍니다. 만약 흐름에 원소가 n개가 부족하면 하나의 흐름을 되돌려줍니다. limit (n) 와 서로 보완합니다.
Stream distinct()
흐름을 통해 생성된 요소의hashCode()와 equals()를 멋지게 선택하여 중복 요소를 제거합니다
Stream map(Function super T,? extends R> mapper)
lambda를 수신하여 원소를 다른 형식으로 바꾸거나 정보를 추출하고 함수를 매개 변수로 수신합니다. 이 함수는 원소에 적용되고 새로운 원소로 비추어집니다.
(3) 작업 종료
일반적인 종료 작업은 다음과 같다.
메서드
묘사
boolean allMatch(Predicate super T> predicate)  
모든 요소가 일치하는지 확인
boolean anyMatch(Predicate super T> predicate)  
하나 이상의 요소가 일치하는지 확인
boolean noneMatch(Predicate super T> predicate)  
일치하는 요소가 없는지 확인
Optional findFirst()  
첫 번째 요소 반환
Optional findAny()  
현재 흐름의 임의의 요소를 되돌려줍니다
long count()
흐르는 원소의 총 개수를 되돌려줍니다
Optional max(Comparator super T> comparator)  
반환 스트림 최대값
Optional min(Comparator super T> comparator) 
반환 흐름의 최소값
사례:
@Test
	public void test2() {
		List list = Arrays.asList("a","d","e","b","c");
		//    
		list.stream()
		.sorted()
		.forEach(System.out::println);
		
		//    
		List p = new ArrayList<>();
		p.add(new Person("aa",18,100.0));
		p.add(new Person("cc",16,150.0));
		p.add(new Person("bb",20,180.0));
		p.stream()
		.sorted((e1,e2)->{
			if(e1.getAge()==e2.getAge()) {
				return e1.getName().compareTo(e2.getName());
			}else {
				return e1.getAge()-e2.getAge();
			}
		}).forEach(System.out::println);
	}
	class Person {
		private String name;
		private int age;
		private double score;

		public Person() {

		}

		public Person(String name, int age, double score) {
			this.name = name;
			this.age = age;
			this.score = score;
		}
		

		public String getName() {
			return name;
		}

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

		public int getAge() {
			return age;
		}

		public void setAge(int age) {
			this.age = age;
		}

		public double getScore() {
			return score;
		}

		public void setScore(double score) {
			this.score = score;
		}

		@Override
		public String toString() {
			return "Person1 [name=" + name + ", age=" + age + ", score=" + score + "]";
		}

	}

 
 
 

좋은 웹페이지 즐겨찾기