26일차 내용 정리

채공부·2025년 6월 30일

Git

🔴 Fork & Clone

Fork : 다른 사람의 GitHub 저장소를 내 GitHub 저장소로 복제
Create a new fork ➜ 동일한 저장소 이름은 불가능하므로 이름 변경 후 복제 가능

Clone : 로컬 컴퓨터에 저장소를 복제
git_repository 에서 git bash 열기
git clone 복제한_저장소_URL
VS Code 에서 해당 폴더 단독 실행 (git_repository/acorn202505_visual_work2)
⭐ Fork 와 Clone 은 한 번만 수행하면 된다

🔴 브랜치 관리

master 브랜치는 readonly 용도
작업은 항상 새 브랜치에서 진행
➜ 충돌 방지를 위해 master 에서 직접 작업 및 커밋❌

<브랜치 생성 & 이동>
git branch study : study 브랜치 생성
git switch study : study 브랜치로 이동

<변경 사항 적용 후 커밋>
javascript 폴더에 my_test.html 파일 생성하고 h1 요쇼 추가 후
"+""my_test.html 추가함" 라는 commit 메세지 작성 후 ✔Commit click

git switch master : master 브랜치로 이동 ➜ 방금 생성한 my_test.html 파일 사라짐

🔴 원격 저장소 구성

origin : My Com ➜ My GitHub = 나의 GitHub 원격 저장소
upstream :  My Com ➜ Teacher's GitHub = 선생님의 GitHub 저장소

<upstream 등록>
git remote add upstream 선생님_저장소_URL : 저장소 등록
git remote -v : 등록된 원격 저장소 확인
git status : 현재 상태 확인 ➜ 워킹트리가 클린한 상태

🔴 원격 저장소 동기화

  • 만일 선생님의 master 브랜치 변경사항을 내 저장소에 반영하려면?
git switch master : master 브랜치로 이동
git pull upstream master : upstream으로부터 master 브랜치 이력 내려받기
							   ⤷ 선생님 저장소(master)에서 최신 이력 가져오기
git push origin master : 내 저장소(master)에 반영
  • 브랜치 충돌 방지 Tip
git switch master
git branch -d study : 기존 study 브랜치 삭제
git branch study : 새로 study 브랜치 생성
git switch study

🔴 기능 개발용 브랜치 생성 & PR

<작업 브랜치 생성>
git switch master : master 브랜치로 이동
git branch 내_이름/lab1 : 새로운 브랜치 생성
git switch 내_이름/lab1 : 해당 브랜치로 이동

<기능 구현 후 내 GitHub에 push>
our_project 폴더 생성하고 내이름.html 파일 생성
"+""내이름.html 추가함" 라는 commit 메세지 작성 후 ✔Commit 
git push origin 내_이름/lab1 : 내 GitHub로 push

<Pull Request(PR) 생성>
1. 내 GitHub 저장소로 가서 Compare & pull request click
2. 메세지 작성 후 Create pull request click
3. 전송된 pr을 선생님이 확인 
⭐ PR 후 merge가 완료되면 해당 브랜치는 삭제하는 것이 좋다

JAVA

HashSet

HashSet = Set 인터페이스를 구현한 클래스

  1. 순서가 없다
  2. key값이 없다
  3. 중복을 허용하지 않는다
  4. 어떤 data를 묶음(집합)으로 관리하고자 할 때 사용
ArrayList ➜ 인덱스로 관리
HahMap ➜ Key 값으로 관리
HashSet ➜ 인덱스 X, key X, 묶음 (집합)
  • 중복값 허용하지 않는다
Set<Integer> set1 = new HashSet<>();
set1.add(10);
set1.add(20);
set1.add(30);
set1.add(40);
set1.add(10);
set1.add(50);
set1.add(20);
		
// 문자열을 저장할 수 있는 HashSet 객체
Set<String> set2 = new HashSet<>();
set2.add("유재석");
set2.add("박명수");
set2.add("정준하");
set2.add("정형돈");
set2.add("노홍철");
set2.add("하하");
set2.add("유재석");
  • 순서가 없다
// Set 객체에 저장된 모든 아이쳄을 순서대로 보장할 수는 없지만 모두 참조해서 사용해 보기
set1.forEach((item)->{
	// set1 은 Set<Integer> 이기 때문에 item 은 Integer type 이 된다
	Integer tmp = item;
	System.out.println(tmp);
});
		
set2.forEach((item)->{
	// set2 는 Set<String> 이기 때문에 item 은 String type 이 된다
	String tmp = item;
	System.out.println(tmp);
});
  • Consumer<>()
    • 메소드 1개짜리 객체 전달
    • forEach() 내부에서 Consumer type의 객체의 메소드가 호출
    • 해당 메소드가 accept() 메소드가 확실한 상황
set2.forEach(new Consumer<String>() {
	@Override
	public void accept(String t) {
    
	}
});
  • Iterator
  1. hashnext() : 다음 걸 가지고 있는가? ➜ true, false
  2. next() : 가지고 있다면 꺼내라
// Set 의 generic 이 Iterator 의 generic 이 된다
Iterator<String> it = set2.iterator();
	
while(it.hasNext()) { // 다음 item 이 있는지 확인해서
	// 다음 item 을 얻어낸다 (item 의 type 은 Iterator 의 Generic type)
	String item = it.next();
	// 얻어낸 item 을 사용하고 또 다음 item 이 있는지 위에서 확인이 된다
	System.out.println(item);
}
박명수 ⭣ true
정형돈 ⭣ true
유재석 ⭣ true
정준하 ⭣ true
 하하  ⭣ true
노홍철 ⭣ truefalse

List

  • Collection<E> , Iterable<E> , SequencedCollection<E>

  • Set가 List의 중복은 없애주는 역할을 한다

  • Set.of()

// Set 클래스의 of() 라는 static 메소드를 이용해서 read only Set 객체를 만들 수도 있다
		Set<String> set1 = Set.of("A", "B", "c", "D");
		Set<String> set2 = Set.of("C", "D", "E", "F");
  • 중복된 데이터가 들어 있는 List
List<String> names = List.of("kim", "lee", "lee", "park");
  • List의 Collection type ➜ 다형성 확인
Collection<String> collec = names; // 다형성 확인
  • HashSet 객체 생성 ➜ 중복 제거
Set<String> namesSet = new HashSet<String>(names);
  • ArrayList 객체 생성 ➜ 인덱스로 관리 가능
List<String> names2 = new ArrayList<>(namesSet);

while문

  • 해당 위치에 참조되는 값이 false가 될 때까지 계속 반복하는 반복문
  • 무한 루프를 구성하거나 정확한 반복 횟수를 알 수 없을 때 많이 사용
int i = 0;

while(i<5){
	System.out.println(i+"반복 시작");
	i++;
}
  • 무한 루프
int j = 0;
while(true) {
	System.out.println(j+"반복 시작");
	j++;
}
  • break = 반복문 탈출
int j = 0;
while(true) {
	System.out.println(j+"반복 시작");
	j++;
    if(j == 5) {
		break; // 반복문 탈출
	}
}

랜덤 번호 예제

Collections.shuffle() : 무작위 섞기 (랜덤)
Collections.sort() : 오름차순 정렬

public static void main(String[] args) {

	// 1. 로또 번호를 담을 HashSet 객체를 생성해서 Set type set1 이라는 지역변수에 담아 보세요
	Set<Integer> set1 = new HashSet<>();
		
	// 2. Random 객체를 생성해서 참조값을 ran 이라는 지역변수에 담아 보세요
	Random ran = new Random();
		
	// 3. while 문을 이용해서 랜덤한 번호를 set1 에 반복적으로 담아 보세요
	// while 문은 무한 루프로 만들고 while 문 탈출 조건은 set1.size() 가 6이 되면 탈출해 보세요
	// ran.nextInt(45) + 1 은 1~45 사이의 랜덤한 정수를 얻어낼 수 있습니다
	while(true) {
    	int ranNum = ran.nextInt(45)+1;
		set1.add(ranNum);
		if(set1.size() == 6) {
			break;
		}
	}
    
	// 4. set1 에 담긴 번호를 모두 하나씩 콘솔창에 출력해 보세요
	set1.forEach((item)->{
		System.out.print(item + " ");
	});
		
	// 5. AI 에 물어봐서 set1 에 담긴 내용을 List 에 담은 다음 오름차순 정렬해 보세요
	List<Integer> nums = new ArrayList<>(set1);
	Collections.sort(nums);
		
	// 6. 오름차순 정렬된 번호를 하나씩 순서대로 콘솔창에 출력해 보세요
	System.out.println();// 개행 기호 출력
	nums.forEach(item-> System.out.print(item + " "));
}

try-catch-finally문

In JavaScript

try{
	예외 발생 가능성이 있는
} catch(e){
  		 ⤷ object type
	e에는 발생한 예외의 정보가 들어 있다
}

In Java

try{
	예외 발생 가능성이 있는 code 블럭
} catch(예외 type e){
				  ⤷ 발생한 예외의 종류에 따라서 type이 다르다
	e에는 발생한 예외의 정보가 들어 있다
}

NumberFormatException

  • 문자열을 숫자로 변환하려 할 때, 잘못된 형식일 경우 발생하는 예외
public static void main(String[] args) {
		Scanner scan=new Scanner(System.in);
		System.out.println("숫자입력:");
		//숫자 형식의 문자열을 입력 받는다 "10"  "20" "10.1" 등등
		String inputNum=scan.nextLine();
		
		try {
			//입력한 숫자를(문자열) 실제 숫자로 바꾼다.
			double num=Double.parseDouble(inputNum);
			//입력한 숫자에 100 을 더한다.
			double result=num+100;
			System.out.println("입력한 숫자 + 100 :"+result);
		}catch(NumberFormatException nfe) {
			/*
			 * 실행 스택에서 일어난 일을 콘솔창에 출력하기
			 * (자세한 에외 정보를 예외 객체가 콘솔창에 출력하게 하기)
			 * */
			nfe.printStackTrace();
		}
		System.out.println("무언가 중요한 마무리 작업을 하고 main 메소드가 종료 됩니다.");
	}

ArithmeticException

  • 잘못된 계산이 발생할 때 던져지는 예외
  • .getMessage : error 메시지 지정
public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		System.out.print("나눌수 입력:");
		String inputNum1 = scan.nextLine();
		System.out.println("나누어 지는 수 입력:");
		String inputNum2 = scan.nextLine();
		
		try {
			// 문자열 형태의 숫자를 실제 정수로 변경하기
			int num1 = Integer.parseInt(inputNum1);
			int num2 = Integer.parseInt(inputNum2);
			// 계산하기
			int result = num2/num1;
			int result2 = num2%num1;
			System.out.println(num2+" 를 "+num1+" 으로 나눈 몫 : "+result);
			System.out.println(num2+" 를 "+num1+" 으로 나눈 나머지 : "+result2);
		}catch(NumberFormatException nfe) {
			// 예외 객체에 담긴 메세지
			System.out.println(nfe.getMessage());
			System.out.println("숫자 형식으로 입력해주세요");
		}catch(ArithmeticException ae) {
			System.out.println("어떤 수는 0으로 나눌 수 없습니다");
		}
		System.out.println("main 메소드가 정상 종료 됩니다");
	}

Exception

  • 예외 상황을 처리할 때 사용하는 최상위 클래스
  • 모든 예외는 Exception type 이기 때문에 어떤 예외가 발생하더라도 여기는 반드시 실행
try{
	...  
} catch(Exception e) {
	e.printStackTrace();
}

finally{ }문

  • 예외가 발생하건 말건 반드시 실행이 보장되는 블럭
    중요한 작업을 여기서 주로 수행
try{
	...  
} catch(...) {
	...
} finally {
	...
		}

Exception + finally

public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		System.out.print("나눌수 입력:");
		String inputNum1 = scan.nextLine();
		System.out.println("나누어 지는 수 입력:");
		String inputNum2 = scan.nextLine();
		
		try {
			int num1 = Integer.parseInt(inputNum1);
			int num2 = Integer.parseInt(inputNum2);

			int result = num2/num1;
			int result2 = num2%num1;
			System.out.println(num2+" 를 "+num1+" 으로 나눈 몫 : "+result);
			System.out.println(num2+" 를 "+num1+" 으로 나눈 나머지 : "+result2);
		}catch(Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println("중요한 마무리 작업을 합니다!");
		}
		System.out.println("main 메소드가 정상 종료 됩니다");

RuntimeException

Thread.sleep() : 실행의 흐름을 잡아먹는 시간을 정한다

  • Thread.sleep( ) 메소드 내부에서는 RuntimeException 을 상속받지 않은 InterruptedException 이 발생
  • RuntimeException 을 상속받지 않은 예외는 예외 처리를 의무적으로 해야 한다

처리 방법
1. try-catch 로 묶어주기
2. throw

  • Surround with try/catch 의 경우
// run 버튼을 누르면 실행의 흐름(Thread) 가 main() 메소드에서 시작되는데 이걸 main Thread 라고도 한다
public static void main(String[] args) {
	System.out.println("main 메소드가 시작 되었습니다");
		
	try {
    	// main Thread 가 5000ms(5초) 동안 여기서 잠잔다(멈춘다)
		Thread.sleep(5000);
	} catch (InterruptedException e) {
		e.printStackTrace();		
		}
		System.out.println("main 메소드가 종료 되었습니다");
	}
  • Add throws declaration 의 경우
// run 버튼을 눌렀을 때 Java Virtual Machine 이 main() 메소드를 호출하면서 메인 스레드가 시작된다
public static void main(String[] args) throws InterruptedException {
    // 따라서 여기서 발생하는 예외를 우리가 처리하지 않으면 JVM 이 대신 처리 해준다
	System.out.println("main 메소드가 시작 되었습니다");
		
	// Exception 을 try catch 로 묶지 않으면 예외처리의 주체는 메소드를 호출한 곳에서 처리한다
	Thread.sleep(5000);

	System.out.println("main 메소드가 종료 되었습니다");
}
  • 호출
public static void main(String[] args) {
		MyUtil.drow();
        
		try {
			MyUtil.send();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
  • throw 예약어로 예외 발생시키기
    throw : 예외 객체를 강제로 발생시킬 때 사용
    ➜ 필요한 경우 예외 클래스는 직접 정의해 해당 예외를 원하는 시점에 발생시켜야 할 경우 존재
    throws 한 메소드는 해당 메소드를 호출하는 곳에서 예외 처리를 해줘야 한다
public class WowException extends RuntimeException{ // 1. RuntimeException 를 상속 받는다
	
	// 생성자에 전달되는 예외 메세지를 부모 생성자에 전달한다
	public WowException(String msg) {
		super(msg);
	}
}
  • 랜덤 숫자 추첨 중 7이 나오면 예외 발생
public class MyUtil {
	// 0~9 사이의 랜덤한 정수를 콘솔이 출력하는 메소드인데 우연히 7이 나오면 WowException 이 발생하는 코드
	public static void generate() {
		Random ran = new Random();
		// 0~9 사이의 랜덤한 정수를 발생시켜서
		int ranNum = ran.nextInt(10);
		
		// 만일 우연히 7 이라는 숫자가 나오면
		if(ranNum == 7) {
			throw new WowException("wow! 행운의 lucky 7!");
			
		}
		System.out.println(ranNum+"숫자 추첨 완료");
	}
}
  • 예외 발생 흐름 확인 WowException이 발생하여 예외 발생과 함께 메시지 출력
public static void main(String[] args) {
	System.out.println("main 메소드가 시작됩니다");
	MyUtil.generate();
		
	System.out.println("main 메소드가 종료됩니다");
}

➜ WowException이 발생하여 예외 발생과 함께 메시지 출력

  • try-catch으로 직접 처리
public static void main(String[] args) {
	System.out.println("main 메소드가 시작됩니다");
	try{
		MyUtil.generate();
	}catch(WowException we) {
		System.out.println("WowException 발생");
		System.out.println("얘외 메세지:"+we.getMessage());
	}	
	System.out.println("main 메소드가 종료됩니다");
}

JFrame

  • Graphic User Interface 윈도우 생성
  1. JFrame 클래스를 상속
  2. 생성자에서 초기화 작업
  3. main() 메소드에서 이클래스를 객체를 생성하면 프레임(window) 생성
public class MyFrame extends JFrame{
	// 생성자 
	public MyFrame() {
		// 프레임의 제목 설정
		this.setTitle("나의 프레임");
		// 프레임의 위치와 크기 설정 setBounds(x,y,width, height)
		this.setBounds(100, 100, 500, 500);
		// 종료(x) 버튼을 눌렀을 때 프로세스(app) 전체가 종료된다
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 화면 상에 실제 보이도록 한다
		setVisible(true);
	}
	
}

public static void main(String[] args) {
		new MyFrame();
	}

➜ 계속 활성화 상태이기에 🟥 버튼이나 창의 ❌ 버튼을 누르면 종료

  • GUI 화면 상에 버튼 출력
public class MyFrame extends JFrame{
	// 생성자 
	public MyFrame() {
		// 프레임의 제목 설정
		this.setTitle("나의 프레임");
		// 프레임의 위치와 크기 설정 setBounds(x,y,width, height)
		this.setBounds(100, 100, 500, 500);
		// 종료(x) 버튼을 눌렀을 때 프로세스(app) 전체가 종료된다
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
		// 레이아웃 매니저 객체 생성
		FlowLayout layout = new FlowLayout(FlowLayout.CENTER); // 가운데 정렬
		// 프레임의 레이아웃 만들기
		setLayout(layout);
		// JButton 객체 생성
		JButton btn1 = new JButton("버튼1");
        JButton btn2 = new JButton("버튼2");
        JButton btn3 = new JButton("버튼3");
		// 프레임의 add() 메소드 호출하면서 JButton 객체의 참조값을 전달하면 프레임에 버튼이 배치된다
		add(btn1);
        add(btn2);
        add(btn3);
		
		// 화면 상에 실제 보이도록 한다
		setVisible(true);
	}
	
	// main 메소드 만들기
	public static void main(String[] args) {
		new MyFrame();
	}
}

버튼 이벤트 처리

addActionListener()

  1. 익명 내부 클래스
btn1.addActionListener(new ActionListener() {
			
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("버튼1을 눌렀네요!");	
	}
});
  1. 람다식
btn2.addActionListener(e->System.out.println("버튼2를 눌렀네요!"));
  1. 별도 클래스 정의
class BtnListener implements ActionListener {
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("버튼3을 눌렀네요!");
	}
}
btn3.addActionListener(new BtnListener());
profile
학원 공부 내용 정리

0개의 댓글