TIL - 2022.02.28 ~03.06

YulHee Kim·2022년 2월 28일
0

코테 주언어 파이썬,, 부언어 자바,,를 위한,, 길 🌟

✏️ 정렬

import java.util.Arrays;

public class Java100_algorithm_SortAlgorithmWithMethod {
	public static void main(String[] args) {

		//[1]: 배열 선언 -> 성적 배열
		int[] scores = {88, 55, 39, 100, 90, 100, 98, 67};

		//[2]: 성적 배열 -> 오름차순 정렬 -> Arrays.sort(배열명); -> 오름차순이 기본정렬 -> import 필요
		// 클래스 메서드로써 Arrays 클래스의 인스턴스 생성없이 바로 사용 가능
		System.out.print("정렬 전");
		for(int i=0; i < scores.length; i++)
			System.out.print(scores[i] + "  ");System.out.println();

		Arrays.sort(scores);

		System.out.print("정렬 후");
		for(int i:scores)
			System.out.print(i + " ");System.out.println();
	}
}

내림차순 정렬

import java.util.Arrays;
import java.util.Collections

public class Java100_algorithm_SortAlgorithmWithMethod2 {
	public static void main(String[] args) {

		//[1]: 배열 선언
		//원하는 정렬 조건 설정 -> 기본형(PrimitiveType)의 배열에는 적용이 안된다
		//래퍼 클래스로 만들어서 적용해야한다.
		//참고로 String 타입은 기본형이 아니다
		Integer[] scores = {88,55,33,100,90,99,77,66};

		//[2]: 내림차순 정렬 -> 추가 옵션 설정 필요 -> (배열명, 컬렉션 reverseOrder)
		//Collections 클래스의 reverseOrder() 메서드 사용 -> import 필요
		System.out.print("정렬 전 = ");
		for(int i=0; i < scores.length; i++)
			System.out.print(scores[i] + " ");System.out.println();

		Arrays.sort(scores, Collections.reverseOrder());
		System.out.print("정렬 후 = ");
		for(int i=0; i < scores.length; i++)
			System.out.print(scores[i] + " ");System.out.println();

		for(int i:scores)
			System.out.print(i + " ");System.out.println();
	}
}

✏️ 순위 매기기

학생들의 성적을 1등부터 순위를 매겨서 출력해보시오

import java.util.Arrays;

public class Java100_algorithm_RankAlgorithm {

	public static void printRanking(int[] scores, int[] ranking) {

		int scores_len = scores.length;
		int ranking_len = scores_len;

		System.out.println("총" + scores_len + "명 학생의 성적과 등수는?");
		for(int i=0; i < scores_len; i++)
			System.out.print(scores[i]+ "점 -->" + ranking[i] + "등    ");
		System.out.println();
	}


	public static void main(String[] args)

	//[1]: 배열 선언 -> 성적 배열, 랭킹 배열 2가지
	int[] scores = {88, 50, 38, 100, 90, 100, 99, 75};
	int s_len = scores.length;
	int[] ranking = new int[s_len];

	// 오름차순으로 배열 정렬
	Arrays.sort(scores);

	//[2]: 순위 처리
	for(int i=0; i < s_len; i++) {

		ranking[i] = 1;

		for(int j=0; j < s_len; j++)
			if(scores[i] < scores[j])
				ranking[i]++;
	}

	//[3]: 출력 -> 별도의 메서드 호출
	printRanking(scores, ranking);


}

✏️ 배열 빈도수

배열 내 숫자들의 각 빈도 수를 출력하는 코드를 구현하시오

public class Java100 {
	public static void main(String[] args) {

		//배열 선언
		int[] target = {1, 3, 3, 2, 1, 1, 3, 0, 1, 2};

		//배열내 숫자들의 빈도 수 출력하기
		int[] ar = new int[4];

		for(int i=0; i < target.length; i++)
			ar[target[i]]++;
		
		for(int i=0; i <ar.length; i++)
			System.out.println(i + "번 숫자 --> " + ar[i] + " 번 ");
		System.out.println();
	}

}

홀수, 짝수 구하기

public class Java100 {
	public static void main(String[] args) {

		int number = 1;

		// 반복문 돌면서 홀수인지 체크 -> 홀수면 continue
		while(number <= 30) {

			if(number % 2 != 0){
				number++;
				continue;
			}
			System.out.print(number+" ");
			number++;
		}
		System.out.println();

	}
}

✏️ continue label이란

public class Java100 {
	public static void main(String[] args) {

		//[1]: 이중 반복문
		outerloop:
		for(int i=0; i <= 3; i++) {
			for(int j=0; j < 10; j++) {

				//출력값
				int output = i * 10 + j;
				
				//짝수만 출력
				if(output % 2 != 0) {
			
					if(j==1){
						System.out.println();
						continue outerloop;
					}
					continue;
				}
				else {
					System.out.print(output+"");
				}
			}
			System.out.println();
		}

	}
}

-> j가 1이면 outerloop label이 선언된 바깥쪽 for문으로 분기하여 그 다음 단계부터 다시 수행

✏️ 구현 문제

문제

한 학급에서 반장 선거를 하는데 3명의 후보자를 두고 7명의 학생이 투표를 하였다. 1~3번 까지의 후보자들 중에서 과반수 이상 득표를 하면 당선이 된다. 투표 박스는 배열의 리스트로 제공되며 여기에는 1~3번 각 후보자의 번호가 기표되어 있다.
(1) 각 후보자가 득표한 득표 수를 출력
(2) 가장 많은 득표 수와 그때의 후보자 번호를 출력
(3) 가장 많이 득표한 후보자의 득표 수가 과반수 이상을 확보하였는지 체크하여 당선 또는 미당선 출력

import java.util.Arrays;

class Solution {
	
	Solution() {}

	public void solutionMethod(int n, int[] vote_box) {

		int[] ar = new int[n+1];

		//[1]: 각 후보자 득표 수 계산
		for(int i=0; i < vote_box.length; i++) {
			ar[vote_box[i]]++;
		}

		for(int i=1; i < ar.length; i++)
			System.out.println(i+"번 후보 -->" + ar[i] + "표");
		//[2]: 가장 많은 득표수와 후보자 출력
		int rst_candidate = 0, rst_max = ar[0];
		for(int i=1; i < ar.length; i++) {
			if(ar[i] > rst_max) {
				rst_max = ar[i];
				rst_candidate = i;
			}
		}
		System.out.println("가장 많은 득표 수 -->" + rst_max + "표 이고, 후보자는 " + rst_candidate + "번 후보자입니다.");

		//[3]: 가장 많은 득표수와 가장 적은 득표수 출력
		Arrays.sort(ar);
		System.out.println("가장 적은 득표 수는 = " + ar[1]);
		System.out.println("가장 많은 득표 수는 = " + ar[ar.length-1]);
		int rst_max = ar[ar.length-1];

		//[4]: 과반수 체크
		boolean majority = rst_max > (vote_box.length/(double)2);
		if(majority)
			System.out.println("과반수 이상 득표했습니다.--> 당선");
		else
			System.out.println("과반수 이상 실패했습니다.--> 미당선");

	}
}

public class Java100 {
	public static void main(String[] args) {

		Solution s1 = new Solution();

		//득표한 표 수를 저장하는 정수형 배열 선언
		int[] vote_box = {1,3,1,3,3,2,2};

		//solutionMethod() 호출 -> 2개 입력 파라미터 값 전달 -> 후보자 수, 투표박스 배열
		s1.solutionMethod(3, vote_box);
	}
}

✏️ 제네릭의 필요성

제네릭의 개념과 필요성에 대해서 예제 코드로 설명하기

class Sample {

	private Object obj;

	Sample(Object x) {
		this.obj = x;
	}

	public Object getObj() {
		return obj;
	}
	
	void printInfo() {
		System.out.println(obj.getClass().getName()); //객체가 속하는 클래스의 정보를 출력하는 메서드
	}
}

public class Java100 {
	public static void main(String[] args){

		//객체 생성 -> 문자열
		Sample s1 = new Sample("안녕하세요~");
		System.out.println(s1.getObj());
		s1.printInfo();
		System.out.println("----------------------");

		//객체 생성 -> 숫자
		Sample s2 = new Sample(100);
		System.out.println(s2.getObj()); //100
		s2.printInfo();

		//객체 생성 -> Object
		Sample s3 = new Sample(new Object());
		System.out.println(s3.getObj());
		s3.printInfo();
		System.out.println("----------------------");

		//위와 같이 사용시 -> 단점
		//s1 -> 문자열
		String str = (String)s1.getObj(); //리턴시 반환 타입이 Object -> 형변환 시켜줘야함
		System.out.println(str.length()); //6
		
		//Object num = s2.getObj();
		//System.out.println(num + 100); //Err
		int num = (int)s2.getObj();

	}
}

✏️ 제네릭 필요성(2)

컴파일 단계에서는 에러가 안나고, 실행 단계에서 ClassCast 오류가 발생하는 상황을 만들어보시오

class Person {
	
	public Object obj;

	Person(Object obj) {
		this.obj = obj;
	}	
}

class Student {
	
	public int grade;

	Student(int grade) {
		this.grade = grade;
	}
}

class Teacher {}

public class Java100 {
	public static void main(String[] args) {

		Person p1 = new Person("안녕하세요~");
		//System.out.println(p1.obj);
		String str = (String)p1.obj;
		System.out.println(str.length()); //6


		Person p1 = new Person(new Student(1));
		Student s1 = (Student)p1.obj;

		// 형변환 -> Cast
		Teacher t1 = (Teacher)p1.obj; //이 부분은 컴파일 단계에서는 에러가 안나고, 실행 단계에서 에러가 남
	}
}

✏️ 제네릭 개념과 사용법

제네릭 개념과 사용법을 예제 코드로 구현해보시오

class Sample<T> {
	
	private T obj;

	Sample(T x) {
		this.obj = x;
	}

	T getObj() {
		return obj;
	}

	void printInfo() {
		System.out.println(obj.getClass().getName());
	}
}

public class Java100 {
	public static void main(String[] args) {

		// 객체 생성 -> String
		Sample<String> s1 = new Sample<String>("안녕하세요");
		System.out.println(s1.getObj());
		s1.printInfo();
		System.out.println("--------------------------");

		Sample<Integer> s2 = new Sample<Integer>(100);

		//형변환 없이 사용하기
		String str = s1.getObj();
		System.out.println(str.length()); // 6
		System.out.println(s2.getObj()+100); // 200

	}
}

✏️ Collection Framework

컬렉션(Collection) 프레임워크란 무엇인지 개념을 설명해보시오

Collection Framework란?

  • 수집품이라는 사전적 의미에서 유추할 수 있듯이 "데이터 값들을 담는 여러 그릇" 정도로 이해하면 된다
  • 내가 만들 프로그램의 데이터 처리를 어떻게 할지 그 특징을 잘 파악하여 컬랙션 내 맞는 그릇(클래스)을 잘 골라 써야한다.
  • 컬렉션 프레임워크는 크게 봤을 때 -> Collection과 Map으로 나뉘고 이 둘은 모두 인터페이스(interface)로 되어있다.
  • Collection은 또 List와 Set으로 나뉘고 이들도 인터페이스 -> 인터페이스를 상속받아 다양한 형태의 배열(클래스)로 사용된다.

Collection

  • Collection(인터페이스) -> 상속 -> List와 Set으로 구분(인터페이스) -> 상속 -> List 계열 구현 클래스 vs Set 계열 구현 클래스
  • List 계열 구현 클래스 -> ArrayList, LinkedList, Vector, Stack
  • Set 계열 구현 클래스 -> HashSet, SortedSet, TreeSet

List vs Set

  • 컬렉션 프레임워크의 핵심 인터페이스들
  • List 인터페이스를 상속하는 클래스들 특징 -> (1)인덱스가 있고 (2)그래서 저장 순서가 유지되고 (3)데이터 중복이 허용
  • Set 인터페이스를 상속하는 클래스들 특징 -> (1)데이터 중복이 허용 안됨

✏️ ArrayList

ArrayList

  • 자바의 배열은 크기를 미리 지정하고 사용했다 -> 그러다보니 넉넉하게 크기를 지정해놓고 사용하곤 한다.
  • 반면 ArrayList는 필요시 언제든지 추가, 삭제가 가능하다
  • List 인터페이스를 상속하므로 인덱스가 있고, 저장 순서가 유지되고, 데이터 중복이 가능하다
  • 또한 제네릭 문법을 사용할 수 있다 -> 만약 제네릭을 사용하지 않는다면 내부적으로 Object 타입으로 처리된다.
  • 사용을 위해서는 상단에 임포트가 필요하다 -> import java.util.ArrayList 또는 import java.util.*;

Collection 프레임워크의 ArrayList를 사용하는 예제 코드를 구현해보시오


import java.util.ArrayList;

public class Java100_collection {
	public static void main(String[] args) {

		// ArrayList를 제네릭이 아닌 Object 타입으로 사용하는 경우
		ArrayList list1 = new ArrayList();

		// 데이터 추가하기 -> add()
		list1.add("홍길동"); //문자열 자료형 저장
		list1.add(20);	//정수 자료형 저장
		list1.add("이순신");
		list1.add(20); //데이터 중복이 가능
		list1.add(new Person());

		// 데이터 가져오기 -> get() -> 이때, 해당 데이터 자료형으로 형변환하여 사용한다.
		System.out.println(list1.get(0)); //홍길동
		String str = (String)list1.get(0);
		System.out.println(str.length()); //3
		int num = (int)list1.get(1); //20
		System.out.println(num + 100); //120

		//출력
		for(int i=0; i < list1.size(); i++)
			System.out.println(list1.get(i) + "");
	}
}

결론
: 제네릭 문법을 사용하지 않으면 ArrayList는 내부적으로 Object 타입으로 처리됨 을 알 수 있다.
그래서 get() 메서드를 사용할 때는 형변환을 주의해야 한다 -> 제네릭을 사용하면 된다

✏️ ArrayList 추가,수정,삭제,출력

import java.util.ArrayList;

public static Java100_collection {
	public static void main(String[] args) {

		//ArrayList 객체 생성 -> 제네릭을 사용
		ArrayList<String> ar = new ArrayList<String>();

		//추가 -> add()
		ar.add("홍길동");
		ar.add("이순신");
		ar.add("강감찬");
		ar.add("을지문덕");
		ar.add("김유신");
		System.out.println(ar.get(3)); //을지문덕
		String str = ar.get(0); //형변환 없이 바로 사용 -> 타입 안전성 높아짐
		//int num = (int)ar.get(0); //컴파일 단계에서 오류 발견

		//수정 -> set(인덱스, 수정값)
		ar.set(3, "징기스칸");
		System.out.println(ar.get(3)); //징기스칸

		//삭제 -> 2가지(하나만 삭제/한꺼번에 삭제) -> remove(인덱스)
		ar.remove(3);
		System.out.println("------[삭제 후 출력]");
		System.out.println(ar.get(0)); //홍길동
		System.out.println(ar.get(1)); //이순신
		System.out.println(ar.get(2)); //강감찬
		System.out.println(ar.get(3)); //김유신
		System.out.println("------[삭제 후 출력]");

		//출력
		for(String str1:ar)
			System.out.println(str1);

		//한꺼번에 삭제 -> removeAll(배열명)
		ar.removeAll(ar);
		System.out.println(ar.size()); //0
		


	}
}

✏️ ArrayList 2차원 배열

컬렉션 프레임워크의 ArrayList 기반으로 2차원 배열을 만들어 요소를 추가하고 출력해보시오

import java.util.ArrayList;

public class Java100_collection {
	public static void main(String[] args){

		//객체 생성
		ArrayList<Integer[]> arr = new ArrayList<Integer[]>();

		//요소 추가 -> add()
		arr.add(new Integer[]{11,12,13,14});
		arr.add(new Integer[]{21,22,23,24});
		arr.add(new Integer[]{31,32,33,34});

		//요소 출력
		for(int i=0; i < arr.size(); i++)
			System.out.println(arr.get(i)[0]); // 11,21,31

		
		//System.out.println(arr.get(0).size()); //Err -> 컬렉션 프레임워크 타입의 길이를 알고 싶을 때
		//System.out.println(arr.get(0).length()); //Err -> 문자열 길이를 알고 싶을 때
		System.out.println(arr.get(0).length); //4 -> 배열의 길이를 알고 싶을 때 사용

		//전체 요소 출력 -> 이중 반복문
		for(int i=0; i < arr.size(); i++) {
			for(int j=0; j < arr.get(i).length; j++)
				System.out.println(arr.get(i)[j]);
		}
	}
}

✏️ Iterator

terator(반복자)란 무엇인가?

  • Collection에 대한 반복자이다

  • 컬렉션 프레임워크 내에는 다양한 컬렉션들이 있는데 요소(원소)를 읽어올 때 Iterator 인터페이스로 표준화 하고 있다.

  • 보통 for 반복문을 사용하여 순회할 때 index로 각 요소를 순회하나 Iterator(반복자)를 이용하면 조금 더 편리하게 할 수 있다.

  • Iterator(반복자)는 인터페이스다 -> 그래서 인터페이스 내 선언된 메서드들이 있다

  • hasNext(), next(), remove() -> 반환타입은 boolean, Object(제네릭), void

  • hasNext) -> 다음 요소가 있는지를 검사하여 true를 리턴

  • next() -> 다음 요소를 리턴 -> 그런 후 다음 위치로 커서가 이동 -> Iterator에서는 삭제하지 않고 커서만 이동

  • remove() -> 제거

  • 임포트 필요 -> import java.util.Iterator;

Iterator 개념과 이를 이용하여 ArrayList 요소를 순회 및 삭제하는 코드를 구현해보시오

import java.util.ArrayList;
import java.util.Iterator;

public class Java100_collection {
	public static void main(String[] args) {

		ArrayList<String> list = new ArrayList<>();

		//요소 추가 -> add()
		list.add("Alligator");
		list.add("Hippo");
		list.add("Ostrich");
		list.add("Donkey");

		//Iterator(반복자) 객체 생성
		//Collection 인터페이스가 iterator()메서드를 정의하고 있고 이를 상속 받는게 List, Set인터페이스이므로
		//List, Set 인터페이스를 상속받아 구현한 클래스들 객체를 통해서 iterator() 메서드를 사용할 수 있음
		Iterator<String> iter = list.iterator();

		//Iterator(반복자) 메서드 사용 -> hasNext(), next(), remove()
		//System.out.println(iter.hasNext()); // true -> 첫번째 요소가 있으므로
		//System.out.println(iter.next()); //Alligator
		//System.out.println(iter.hasNext()); // true -> 두번째 요소가 있으므로
		//System.out.println(iter.next()); //Hippo
		//System.out.println(iter.hasNext()); // true 
		//System.out.println(iter.next()); 
		//System.out.println(iter.hasNext()); // true 
		//System.out.println(iter.next()); 
		//System.out.println(iter.hasNext()); // false
		//System.out.println(iter.next()); // Err


		//요소 출력
		for(String s:list)
			System.out.println(s);


		//while문 활용
		while(iter.hasNext()) {
			System.out.println(iter.next());
		}


		//특정 값만 삭제
		while(iter.hasNext()) {
			String str = iter.next();
			if("Hippo".equals(str)) {
				iter.remove();
				System.out.println("Hippo 삭제");
			}
		}



	}
}


✏️ 반복자 사용 이유

Iterator(반복자)를 쓰는 이유에 대해서 설명해보시오

java.util.ConcurrentModificationException
: 컬렉션 프레임워크를 쓸 때 자주 만나게 되는 에러 메세지

  • 이 오류 메세지는 보통 컬렉션 list 요소를 반복문 안에서 돌리면서 값을 삭제하고자 할 때 발생
  • 보통 반복문 안에서 remove() 메서드를 호출할 때 발생
  • 그 외에도 Iterator(반복자) 객체의 생성 순서에 따라서도 발생 -> 다양하다

한 행씩 삭제하는 경우에는 별 문제가 없으나 반복문 안에서 순회하면서 삭제시에는 반복문 들어가기 전의 기존 list 배열의 size(length)나 index 정보 등이 변경되면서 순회시 정보가 맞지 않아 오류 발생
이를 해결하기 위해서는 Iterator(반복자)를 사용하여 순회하고 그때, iter.remove() 메서드로 처리해야한다.

mport java.util.ArrayList;
import java.util.Iterator;

public class Java100_collection {
	public static void main(String[] args) {

		//객체 생성
		ArrayList<Integer> list = new ArrayList<>();

		//요소 추가 -> add()
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);

		//Iterator(반복자) 객체 생성
		Iterator<Integer> iter = list.iterator();

		//출력 -> 요소 삭제 전
		for(Integer num:list)
			System.out.println(num);

		//요소 삭제 -> 반복문 없이 한개의 요소만 삭제
		//System.out.println(list.get(1)); // 2
		//list.remove(1);
		//System.out.println(list.get(1)); // 3

		//요소 삭제 -> while 반복문 사용
		while(iter.hasNext()) {
			Integer i = iter.next();
			if(i==2) {
				list.remove();
				System.out.println(i+"번 삭제");
			}
		}

		//출력 -> 요소 삭제 후
		for(Integer num:list)
			System.out.println(num);

	}
}

예제

1부터 10 사이의 숫자가 무작위로 10개 출력되는 코드를 구현해보시오
이때, 0은 출력되면 안된다

public class Java100 {
	public static void main(String[] args) {

		//반복문 -> 랜덤 숫자 생성
		//랜덤 숫자 생성중 0을 제외하려면? -> 결과로 나오는 숫자에 1을 더해준다.
		for(int i=0; i < 10; i++) {
			System.out.print(((int)(Math.random()*10) + 1) + "\t");
		}
	}
}
profile
백엔드 개발자

0개의 댓글