코드스테이츠 백엔드 부트캠프 18일차 [Java 심화(Effective)-2]

wish17·2023년 1월 9일
0
post-thumbnail

Java 심화(Effective)

스트림(Stream) Quiz

List를 입력받아, Gender=='"Male"의 평균 나이를 리턴하라.

  • 반복문(for, while) 사용은 금지
  • 회원의 수가 0이거나, 남자 회원이 없는 경우 0을 리턴하라.
  • double 타입을 리턴하라.

나의 풀이

import java.util.*;

public class Solution { 
  public double computeAverageOfMaleMember(List<Member> members) {
    //구현된 Member 클래스의 getName(), getGender(), getAge() 메소드로 해당 Member 클래스의 name, gender, age를 확인할 수 있습니다.
    //TODO..
    return members.stream()
                  .filter(n->n.getGender() == "Male")  // "==" 기초 자료형만 비교가 가능, 어지간하면 문자열 비교는 equals 쓰자.
                  .mapToInt(m -> m.getAge()) // == (Member::getAge)
                  .average()
                  .orElse(0.0); //필터링 외의 값 0.0할당


    //람다식 생략조건 다시 공부!!
    //collect로 하려다 고생..
    
  }

  static class Member {
    String name;
    String gender;
    int age;

    public Member(String name, String gender, int age) {
      this.name = name;
      this.gender = gender;
      this.age = age;
    }

    public String getName() {
      return name;
    }

    public String getGender() {
      return gender;
    }

    public int getAge() {
      return age;
    }
  }
}

람다식 복습하자.

ans

import java.util.*;

public class Solution { 
	public double computeAverageOfMaleMember(List<Member> members) {
    double maleAveg = members.stream()
            .filter(m -> m.getGender().equals("Male")) // 회원의 성별을 받아와서 남자인 경우만 필터링
            .mapToInt(Member::getAge) // 남자 회원들의 나이 받기
            .average() // 남자 회원들의 나이 평균
            .orElse(0.0);
    return maleAveg;
   }
}

List를 입력받아 김으로 시작하는 요소를 리턴하라.

  • 중복 제거
  • 반복문(for, while) 사용은 금지
  • 사전식 순서로 정렬하3

나의 풀이 = ans

import java.util.*;

public class Solution { 
  public String[] filterName(List<String> names) {
    //TODO..
    return names.stream()
    .distinct() //중복을 제거
    .filter(n -> n.startsWith("김")) // 첫 글자가 "김"인 경우만 필터링
    .sorted() // 정렬
    .toArray(String[]::new); // == .toArray(size -> new String[size]);
    // 최종 결과를 문자열 배열로 만들기
  }
}

int 타입을 요소로 가지는 배열을 입력받아 가장 큰 요소를 리턴하라.

  • 반복문(for, while) 사용은 금지
  • 빈 배열을 입력받은 경우 null을 리턴하라.
  • Integer 타입을 리턴하라.

나의 풀이

import java.util.*;

public class Solution { 
  public Integer findBiggestNumber(int[] arr) {
    //TODO..
    if(arr.length == 0){
      return null;
    }else {
      return Arrays.stream(arr)
    .max()
    .getAsInt();
    }
  }
}

ans

import java.util.*;

public class Solution { 
  public Integer findBiggestNumber(int[] arr) {
  
    return arr.length ==0 ? null : Arrays.stream(arr).max().getAsInt();
  }
}

삼항연산자 잘쓰자...

가장 길이가 긴 요소의 길이를 리턴하라.

  • 반복문(for, while) 사용은 금지

나의 풀이

import java.util.*;

public class Solution { 
  public int findLongestLength(String[] strArr) {
    if(strArr.length == 0){
      return 0;
    }else {
      return Arrays.stream(strArr)
      .mapToInt(String::length) // == (str -> str.length())
      .max()
      .getAsInt();
    }
  }
}

ans

import java.util.*;

public class Solution { 
  public int findLongestLength(String[] strArr) {
  
      return Arrays.stream(strArr).
                  .mapToInt(str->str.length())
                  .reduce(0, (a,b) -> a > b ? a : b);
  }
}

reduce를 쓰면 초기값을 0으로 세팅 가능하기 때문에 더 간략하게 가능하다.

List 두 개를 스트림을 이용해 하나의 List로 합치시오.

  • 반복문(for, while) 사용은 금지

나의 풀이

import java.util.*;
import java.util.stream.*;

public class Solution { 
  public List<String> mergeTwoStream(List<String> list1, List<String> list2) {
    //Stream<String> stream1 = list1.stream();
    //Stream<String> stream2 = list2.stream();
    Stream<String> result = Stream.concat(list1.stream(),list2.stream());
    return result.collect(Collectors.toList());
  }
}

List를 출력해야 하는데 Stream 형태로 리턴하려고 해서 계속 고생했다.

ans

import java.util.*;
import java.util.stream.*;

public class Solution { 
  public List<String> mergeTwoStream(List<String> list1, List<String> list2) {
  
    return Stream.concat(list1.stream(),list2.stream()).collect(Collectors.toList());
  }
}

사실 addall하면 더 간단하다. 스트림 연습중이라 굳이 이렇게 푼거다.

12

30 이상인 요소가 3개 이상이면 true를, 그렇지 않다면 false를 리턴하라.

  • 반복문(for, while) 사용은 금지

나의 풀이

import java.util.*;

public class Solution { 
  public boolean isHot(int[] temperature) {
  
    long tem = Arrays.stream(temperature)
    .filter(n -> n>=30)
    .count();

    if(temperature.length !=7){
      return false;
    }else if(tem >=3){
      return true;
    }else return false;
  }
}// count 사용시 long
  • count() 출력은 long타입이다.

ans

import java.util.*;

public class Solution { 
  public boolean isHot(int[] temperature) {
  
  return Arrays.stream(temperature)
  			   .filter(temp -> temp >= 30)
               .count() >=3;

return문에서 바로 대소비교해서 단순화 가능.

두 리스트에서 lastName으로 시작하는 요소들을 모아서 리턴하라

  • 반복문(for, while) 사용은 금지
  • 중복 요소는 삭제하시오
  • 사전식 순서로 정렬하라.

나의 풀이

import java.util.*;
import java.util.stream.*;

public class Solution { 
  public List<String> findPeople(List<String> male, List<String> female, String lastName) {
    //TODO..
    Stream<String> list1 = female.stream()
    .distinct()
    .sorted()
    .filter(n -> n.startsWith(lastName));

    Stream<String> list2 = male.stream()
    .distinct()
    .sorted()
    .filter(n -> n.startsWith(lastName));


    Stream<String> result = Stream.concat(list1,list2);
    return result.distinct().collect(Collectors.toList());
  }
}

ans

import java.util.*;
import java.util.stream.*;

public class Solution { 
	public List<String> findPeople(List<String> male, List<String> female, String lastName) {

    Stream<String> stream = Stream.concat(male.stream(), female.stream()); // 두 리스트를 스트림으로 만든 뒤 합쳐 전체 인원을 대상으로 연산을 진행
    return stream.distinct() // 전체 인원에서 중복 이름을 제거
            .filter(person -> person.startsWith(lastName)) // 인자로 전달받은 성으로 시작하는 이름을 필터링
            .sorted() // 걸러진 이름들을 정렬
            .collect(Collectors.toList()); // stream을 list형태로 변환
  }
}

파일 입출력(I/O)

InputStream, OutputStream

스트림은 단방향으로만 데이터를 전송할 수 있기에, 입력과 출력을 동시에 처리하기 위해서는 각각의 스트림이 필요하다.

오늘의 정리

Stream.concat(a,b) = 스트림a,b를 합쳐서 새로운 스트림을 만들기
stream().disinct() = 중복 제거
fillter(n->n.startsWith(S)=="김") = S의 첫번째 요소가 "김"으로 시작하는 것만 필터링
sorted(Comparator.xxx()) = 정렬 (기본형: 사전순)
count() = 카운팅, 반환은 long타입

  • Stream 반환 타입을 바꿀 때
    List는 collect(collectors.toList())
    Array(배열)은 .toArray(String[]::new);를 사용하자.

  • 배열(Arrays) -> stream

    • Stream<객체 타입> arraysStreamName = Arrays.stream(arrName);
    • 객체 타입 = Integer, String, className 등
  • stram -> Arrays(배열)

    • 배열타입[] arrayName = streamName.toArray(String[]::new)
    • 배열타입[] arrayName = streamName.toArray(size -> new String[size])
  • 일반 배열(Arrays) -> ArrayList

    • List<객체 타입> arrayListName = Arrays.asList(arrayName)
  • 컬렉션(List,set,map) -> stream

    • Stream<객체 타입> streamName = arrayListName.stream()
    • Stream<객체 타입> streamName = setName.stream()
    • Stream<객체 타입> streamName = mapName.stream()
  • stream -> 컬렉션(List,set,map)

    • List<요소 타입> listName = streamName.collect(Collectors.toList())
    • Set<요소 타입> setName = streamName.collect(Collectors.toSet())
    • Map<key타입.value타입> setName = streamName.collect(Collectors.toMap())
  • ArrayList-> stream -> Map

    • Map<요소 타입> mapName = arrayListName.stream().collect(Collectors.toMap(a,b))
  • List -> stream -> Array(배열)

    • listName.stream().toArray(String[]::new)
    • listName.stream().toArray(size -> new String[size])
  • stream -> int, Double

    • int intName = streamName.getAsInt()
    • Double doubleName = streamName.getAsDouble()

Optional
Collectors
Comparator
위 레퍼런스를 참고해 입출력 타입을 명확히 하고 사용하자.

0개의 댓글