[JAVA] 제네릭, 함수형 인터페이스, 스트림

merci·2022년 12월 30일
0

JAVA

목록 보기
2/10

제네릭

//제네릭클래스
class Box<T> {
	private T data;  // 제네릭 클래스는 static을 붙일 수 없다.
    			 // getter, setter도 static을 붙일 수 없다.(가져올 static 필드 x)
 	//제네릭 메소드
    public static <T> T getLast(T[] a) { // 입력받은 배열의 마지막 인덱스 리턴
    	return a[a.length - 1];
    }
}
  • 제네릭 문제
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class J594_2 {
	static double sum=0; //  getAverage1 메소드 에서 사용될 필드
	static List<Double> list = new ArrayList<>();
    
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("5번 입력한 수의 평균 계산");
		for (int i = 0; i < 5; i++) {
			list.add(sc.nextDouble());
		}
        
		System.out.println(list.stream().reduce((double) 0,Double::sum)/list.size());  
													// 스트림을 이용한 평균 계산
		System.out.println(getAverage1(list));
		System.out.println(getAverage2(list));
		sc.close();
	}
	public static <T extends Number> double getAverage1(List<T> t) {
		t.forEach((e)->{sum+=Double.parseDouble(e+"");});  
		return (double)sum/list.size();
	}
	
	public static <T extends Number> double getAverage2(List<T> t) {
		double sum=0;  
		for(T num : t) // sum += num 불가능, 기본연산자는 기본타입만 연산가능
			sum+=Double.parseDouble(num+"");
		return (double)sum/list.size();
	}
}

결과




함수형 인터페이스

람다식을 사용하려면 함수형 인터페이스를 먼저 만들어야 한다.( @FunctionalInterface 어노테이션 붙여서 )
자바에서는 많이 사용하는 함수형 인터페이스를 java.util.function 패키지로 제공한다.

import java.util.List;
import java.util.Vector;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

 public class Test {
	public static void main(String[] args) {
		Function<Integer, Integer> f1 = i -> i*4;
		System.out.println(f1.apply(3)); 		// 12
		
		Function<String, Integer> f2 = s -> s.length();
		System.out.println(f2.apply("hello")); 		// 5
		
		Function<String, Integer> f3 = Integer::parseInt;
		System.out.println(f3.apply("35"));		 // 35(문자열을 정수타입으로 변환)
		
		Function<String, String> f4 = String::toLowerCase;
		System.out.println(f4.apply("HELLO"));		 // hello
		
		BiFunction<Integer, Integer, Integer> b1  = (x1,x2)	-> x1*x2;
		System.out.println(b1.apply(7,38)); 		// 266
		
		Predicate<Integer> p1 = x1 -> x1%2==0;
		System.out.println(p1.test(4)); 		// true (test는 true/false를 리턴)
		
		List<String> list = new Vector<>();
		for (int i = 0; i < 10; i++) {
			list.add(""+i);
		}
		list.forEach(System.out::print); 		//0123456789
		System.out.println();
		
		Supplier<Integer> s = () -> (int)(Math.random()*45+1);
		System.out.println(s.get()); 		// 1~45 난수
	}
}
  • 함수형 인터페이스를 이용한 예제
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Ramda3 {
	static double sum=0.0;
	static double min=0.0;
	static double max=0.0;
	
	@FunctionalInterface
	public interface ArrayProcessing {
		double apply( double[] array);
	}
	public static void main(String[] args) {
		double[] doubleA = { 1,25,6,54,4,87,2,34,37,45,83,42,431,5,38,3};
		ArrayProcessing sum1 = array -> {  // apply 함수내용을 sum1 변수에 저장
			for(double d : array) {sum+=d; } 
			return sum;};    
				
		ArrayProcessing min1 = array -> {
			min=array[0]; 
			for(double d : array) { min=min>d?d:min; } 
			return min;};
				
		ArrayProcessing max1 = array -> {
			max=array[0]; 
			for(double d : array) { max=max>d?max:d; } 
			return max;};		
		
		System.out.println(sum1.apply(doubleA));	// 897.0
        System.out.println(min1.apply(doubleA));	// 1.0
		System.out.println(max1.apply(doubleA));	// 431.0
	}
}






스트림

스트림은 SQL과 유사해서 선언 -> 작동
스트림은 큰 컬렉션을 효율적으로 처리하기에 좋다
( parallelStream() 메소드 이용해서 다중코어 아키텍처를 활용할 수 있다. )
스트림은 생성 -> 처리 (필터링,매핑,정렬,축소) -> 종말 단계를 거친다.

매핑단계에서는 기존 데이터를 변형하여 새로운 데이터를 생성
정렬단계에서 사용하는 메소드
.sorted(Comparator.reverseOrder()) 는 인수를 넣을수 없어서 전 단계의 매핑에서 인수를 하나로 만들어줘야 함
.sorted(Comparator.comparing(인수).reversed() 는 매핑이 없어도 정렬이 가능하다.
추가 정렬은 .thenComparing(인수) 를 이어 붙이면 된다.

Stream<String> stream2 = Stream.of("JAVA", "HTML", "JAVASCRIPT", "CSS");
		stream2.sorted(Comparator.reverseOrder())
        	   .forEach(s -> System.out.print(s + " "));
        // 결과 JAVASCRIPT JAVA HTML CSS 

축소연산(reduce)를 간단하게 표현하자면.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Ramda3 {
	static double sum=0.0;
	static double min=0.0;
	static double max=0.0;
	
	@FunctionalInterface
	public interface ArrayProcessing {
		double apply( double[] array);
	}
	
	public static void main(String[] args) {
		double[] doubleA = { 1,25,6,54,4,87,2,34,37,45,83,42,431,5,38,3};
        // 스트림을 이용하여 정적배열을 리스트로 변환하는 방법
		List<Double> doublelist = Arrays.stream(doubleA)         
		.boxed()
		.collect(Collectors.toList());

		System.out.println(doublelist.stream()
      			  .reduce( (double) 0,Double::sum) );  //897.0        
		System.out.println(doublelist.stream()
      			  .reduce( doublelist.get(0),Double::min) ); // 1.0
		System.out.println(doublelist.stream()
      			  .reduce( doublelist.get(0),Double::max) ); // 431.0
	}
}

				// ++++ 배열을 리스트로 변환하는 방법
                
		List<Double> doublelist = new ArrayList<>();  // forEach 이용
		for(double temp : doubleA) {
			dd.add(temp);
		}
		
		List<Double> doublelist = Arrays.stream(doubleA)   // 스트림 이용
				.boxed()     // 이 메소드가 기본타입을 래퍼클래스로 변환시켜준다
				.collect(Collectors.toList());
               
               // 문자열 배열을 Arrays.asList() 를 이용하여 변환하면 된다.
  • 스트림 이용한 간단한 예제들
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class Stream4 {
	public static void main(String[] args) {
		List<Color> list = Arrays.asList(new Color("red","#FF0000"),
       		 	new Color("yellow","#FFFF00"),new Color("blue","#0000FF"),
                new Color("brown","#A52A2A"));
                
		List<Color> result = 
     				    list.stream()
							.sorted(Comparator.comparing(Color::getName))
							.collect(Collectors.toList());
		System.out.println(result);
        // 결과 [blue #0000FF, brown #A52A2A, red #FF0000, yellow #FFFF00]
	}
}
class Color {
	String name;
	String hexacode;
	public Color(String name, String hexacode) {
		this.name = name;
		this.hexacode = hexacode;
	}
	public String getName() {
		return name;
	}
	@Override
	public String toString() {
		return name + " "+ hexacode;
	}
}
profile
작은것부터

0개의 댓글