//제네릭클래스
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;
}
}