새소식

TIL

[TIL] 240502 <자바> 람다,스트림,Optional + Git 심화 특강(2)

  • -

 

[13. 모던자바 (람다, 스트림, Optional)]

 

Java 8에서 새롭게 추가된 개념

1. 함수형 프로그래밍의 기능들

 

(1) 함수를 일급 값으로! (메서드 참조 기능의 도입)

      >> 값으로 전달할 함수 생성

// Car 클래스 내부에 두 메서드 구현

public static boolean hasTicket(Car car) {
        return car.hasParkingTicket;
}

public static boolean noTicketButMoney(Car car) {
        return !car.hasParkingTicket && car.getParkingMoney() > 1000;
}

 

      >> 함수형 인터페이스

interface Predicate<T> {
    boolean test(T t);
}

 

 

!!!함수를 값으로 처리하면 되므로, 거의 똑같은 두 개의 함수 필요없음!!!

public static List<Car> parkingCarWithTicket(List<Car> carsWantToPark) {
        ArrayList<Car> cars = new ArrayList<>();

        for (Car car : carsWantToPark) {
            if (car.hasParkingTicket()) {
                cars.add(car);
            }
        }

        return cars;
  }

public static List<Car> parkingCarWithMoney(List<Car> carsWantToPark) {
    ArrayList<Car> cars = new ArrayList<>();

    for (Car car : carsWantToPark) {
        if (!car.hasParkingTicket() && car.getParkingMoney() > 1000) {
            cars.add(car);
        }
    }

    return cars;
}

 

   🔻   🔻   🔻   🔻   🔻   🔻   🔻   🔻   🔻   🔻   🔻

      >> 새로운 함수

// 변경점 1 : Predicate<Car> 인터페이스를 타입 삼아 함수를 전달합니다!
public static List<Car> parkCars(List<Car> carsWantToPark, Predicate<Car> function) {
      List<Car> cars = new ArrayList<>();

      for (Car car : carsWantToPark) {
		// 변경점 2 : 전달된 함수는 다음과 같이 사용됩니다!
          if (function.test(car)) {
              cars.add(car);
          }
      }

      return cars;
  }

 

      >> 실제 사용 : 함수를 값으로 취급하기 때문에, 함수를 참조로 불러서 사용 가능!

parkingLot.addAll(parkCars(carsWantToPark, Car::hasTicket));
parkingLot.addAll(parkCars(carsWantToPark, Car::noTicketButMoney));

 

 

 


(2) 람다 :익명함수 (이름이 없는 함수로, 일급 객체로 취급, 간단하고 한번만 사용될 경우)

// 기본적으로 문법은 다음과 같습니다.
(파라미터 값, ...) -> { 함수 몸체 }


// 아래의 함수 두개는 같은 함수입니다.
// 이름 반환타입, return문 여부에 따라 {}까지도 생략이 가능합니다.
public int toLambdaMethod(int x, int y) {
	return x + y;
}

(x, y) -> x + y


// 이런 함수도 가능하겠죠?
public int toLambdaMethod2() {
	return 100;
}

() -> 100


// 모든 유형의 함수에 가능합니다.
public void toLambdaMethod3() {
	System.out.println("Hello World");
}

() -> System.out.println("Hello World")

 

// 주말의 주차장 추가
ArrayList<Car> weekendParkingLot = new ArrayList<>();

weekendParkingLot
.addAll(parkCars(carsWantToPark, (Car car) -> car.hasParkingTicket() && car.getParkingMoney() > 1000));

 



 

2. 스트림

- 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소
- 컬렉션이 데이터 저장&접근에 초점 맞춘 인터페이스라면, 스트림은 데이터 처리에 초점 맞춘 인터페이스
- collection에 정의되어 있기 때문에, 모든 컬렉션을 상속하는 구현체들은 스트림 반환 가능
- 원본 데이터를 변경하지 않고, 일회용임

- 한 번 더 추상화된 자료구조와 자주 사용하는 프로그래밍 API를 제공한 것
- 자료구조를 한 번 더 추상화했기 때문에, 자료구조의 종류에 상관없이 같은 방식으로 다룰  수 있음
   ( + 병렬 처리에 유리한 구조로 조건부로 성능도 챙길 수 있)
- 자료구조의 “흐름”을 객체로 제공해 주고, 그 흐름 동안 사용할 수 있는 메서드들을 api로 제공



<스트림 API>

https://www.baeldung.com/java-8-streams

 

  • filter() : 함수를 파라미터로 전달받아 false를 반환한 스트림의 원소들을 제거
List<Car> benzParkingLot =

				// 1. carsWantToPark의 스트림값을 받아와서
                carsWantToPark.stream()
                
				// 2. (스트림 가공)
                // 거기 구현되어 있는 filter()메서드를 사용.
				// filter메서드는 함수를 파라미터로 전달받으며
				// false를 반환한 스트림의 원소들을 제거
                .filter((Car car) -> car.getCompany().equals("Benz"))
                
				// 3. 이 결과도 반환을 받아서 다시 리스트로 묶어줌 (스트림 결과 만들기)
                .toList();

 

  • forEach() : 각각의 원소에 넘겨받은 함수를 실행해줌
List<String> carNames = Arrays.asList("Series 6", "A9", "Ionic 6");

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

// 결과 
// Series 6
// A9
// Ionic 6

 

  • map() : 넘겨받은 토대로 값을 변환시키는데 주로 사용
carNames.stream()
	.map(name -> name.toUpperCase()).toList();

// 결과
// ["SERIES 6", "A9", "IONIC 6"]

 

 

 

 

Optional<T> 클래스를 사용해 Null Pointer Exception을 방지 가능 (null이 올 수 있는 값을 감싸는 Wrapper 클래스임)
Optional이 비어있더라도, 참조해도 Null Pointer Exception가 발생하지않음!

  • 값이 null인 Optional 생성하기
Optional<Car> emptyOptional = Optional.empty();

 

  • 값이 있는 Optional 생성하기
Optional<Car> hasDataOptional = Optional.of(new Car());

 

  • 값이 있을수도 없을수도 있는 Optional 생성하기
Optional<Car> hasDataOptional = Optional.ofNullable(getCarFromDB());

 

  • Optional 객체 사용하기 (값 받아오기)
Optional<String> carName = getCarNameFromDB();

// orElse() 를 통해 값을 받아옵니다, 파라미터로는 null인 경우 반환할 값을 적습니다.
String realCarName = carName.orElse("NoCar");


// 위는 예시코드고 실제는 보통 아래와 같이 사용하겠죠?
String carName = getCarNameFromDB().orElse("NoCar");


// orElseGet()이라는 메서드를 사용해서 값을 받아올 수 있습니다.
// 파라미터로는 없는 경우 실행될 함수를 전달합니다.
Car car = getCarNameFromDB().orElseGet(Car::new);


// 값이 없으면, 그 아래 로직을 수행하는데 큰 장애가 되는경우 에러를 발생시킬수도 있습니다.
Car car = getCarNameFromDB()
						.orElseThrow(() -> new CarNotFoundException("NO CAR!));

 

 

 

 


 

Git 심화 특강

 

1.  브랜치 활용하기

브랜치(복사본) 생성 명령어 : git branch 브랜치이름

브랜치 확인 명령어 : git branch ( + 키보드 q로 빠져나가기)

브랜치 이동 명령어 : git switch 브랜치이름 / git checkout 브랜치이름

 

브랜치 한번에 생성&이동 명령어 : git switch -c 브랜치이름 / git checkout -b 브랜치이름

 

새로운 브랜치에서 코드 수정 : 
1. git add .
2. git commit -m "저장 메시지"
- 새로운 브랜치에서 코드를 수정했다고 main의 코드가 바뀌지는 않음!

 

수정된 브랜치 내용을 main에 합치기 : 
1. git switch 최종브랜치이름(main)
2. git merge 합칠브랜치이름(login)

 

 

 

2.  Pull Request 활용하기 (Github)



1. github에 업로드하기 : git push origin 브랜치명(login)

2. github에서 pull request 생성

로컬 main 브랜치로 이동 : git checkout 브랜치명
해보면 login브랜치에서 만든 기능이 적용되어있지 않다!

3. github 코드 반영 : git pull origin 브랜치명 (내 로컬에도 반영)

 

 

 

3.  협업 실전 가이드

 

문제1) 완벽하게 기능개발해야 머지가능
=> 해결 : 개발용 브랜치에서 개발
                (배포용,테스트용,기능개발용)-기능개발용에서 해서 테스트용에 합치고 배포할때만 배포용에 적용

문제2) 그냥 합치면 위험
=> 해결 : 로컬에서 먼저 테스트(push해서 합치기 전에 내컴퓨터에 테스트용 pull 먼저 해와서 테스트 & 충돌시 해결법 알아놓기)

 

 

1) 초기세팅

  • <팀장>

1. 초기 코드 작성 및 깃허브 업로드

   (1) 폴더생성  
   (2) 초기코드 작성
   (3) git init, add, commit
   (4) Github 레포지토리 생성
   (5) Github 업로드 (git push)

2. dev(develop) 브랜치 생성 (테스트용)

   (1) git switch -c dev (로컬에서 dev 브랜치 생성)

   (2) git push origin dev (github에도 반영)

3. github에서 dev브랜치를 default로 설정 (Settings - Defualt branch-설정-dev선택하고-update)

4. 팀원들을 collaborator로 등록 (settings-collaborators)

 

  • <팀원>

5. 레포지토리 주소 복사해가서 작업할 폴더를 vscode에서 연 후 터미널에서 git clone 주소.(점빼먹지말기)

 

 

2) 기능 개발 시작

1. 기능 브랜치 생성 및 기능 개발 코드 작성 : git switch -c 기능브랜치명     &     코드 수정하고 git add,commit,push

2. pull request 생성

3. 코드 작성자: 리뷰 요청하기

4. 코드 리뷰어: 리뷰하기

5. 합치기 전 내 로컬에서 충돌 해결 및 테스트 : 기능브랜치에서 git pull origin dev

6. merge
  (1) 수정 사항 있는 경우 git add,commit,push 
  (2) github에서 merge 클릭

 

 

3) 추가 기능 개발

1. 내 로컬의 dev에도 변경 사항 반영  
   (1) dev 브랜치로 이동 (git checkout dev / git switch dev)
   (2) git pull origin dev

2. 다음 기능 개발 ( 2)반복 )

 


 

.gitignore : git으로 관리하고 싶지 않거나 github에 업로드하고 싶지 않은 파일을 여기에 작성

아래 사이트 활용하여 검색박스 안에 VisualStudioCode, Python, macOS, Windows 등 원하는 조건 입력!

 

gitignore.io

Create useful .gitignore files for your project

www.toptal.com

 

 

 

README.md : 프로젝트의 설명 혹은 프로젝트 협업 시 세팅방법 등을 작성하는 파일

 

 

<비밀번호 대신 사용하는 git token 설정하는 법>

  • 공식문서
 

Managing your personal access tokens - GitHub Docs

You can use a personal access token in place of a password when authenticating to GitHub in the command line or with the API.

docs.github.com

 

 

GitHub: Let’s build from here

GitHub is where over 100 million developers shape the future of software, together. Contribute to the open source community, manage your Git repositories, review code like a pro, track bugs and fea...

github.com

 

  • 블로그
 

깃허브 github personal access token 발급하는 방법

1. 오른쪽 상단에 프로필 아이콘을 클릭 하시면 아래 그림과 같이 [Settings] 메뉴가 보이실겁니다. 해당 메뉴를 클릭합니다. 2. Settings 화면에서 좌측 메뉴에 [Developer settings] 메뉴가 있습니다. 클릭

lifefun.tistory.com

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.