diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f1ad17c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,48 @@ + +# Created by .ignore support plugin (hsz.mobi) +### Java template +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +.DS_Store +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar +/out/ +/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr \ No newline at end of file diff --git a/.idea/2021-Java-Study-1.iml b/.idea/2021-Java-Study-1.iml new file mode 100644 index 00000000..d6ebd480 --- /dev/null +++ b/.idea/2021-Java-Study-1.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..b2e511f6 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 00000000..549566a9 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1610777331766 + + + + + + + + + \ No newline at end of file diff --git a/image/img.jpg b/image/img.jpg new file mode 100644 index 00000000..93b4d2b9 Binary files /dev/null and b/image/img.jpg differ diff --git "a/racingcar\354\213\244\354\212\265/java/Application.java" "b/racingcar\354\213\244\354\212\265/java/Application.java" new file mode 100644 index 00000000..282cf995 --- /dev/null +++ "b/racingcar\354\213\244\354\212\265/java/Application.java" @@ -0,0 +1,7 @@ +import utils.GameUtils; + +public class Application { + public static void main(String[] args) { + GameUtils.run(); + } +} diff --git "a/racingcar\354\213\244\354\212\265/java/inpututils/InputValidator.java" "b/racingcar\354\213\244\354\212\265/java/inpututils/InputValidator.java" new file mode 100644 index 00000000..b17c2fda --- /dev/null +++ "b/racingcar\354\213\244\354\212\265/java/inpututils/InputValidator.java" @@ -0,0 +1,23 @@ +package inpututils; + +public class InputValidator { + private static final int MAX_NAME = 5; + + public static void nameValidator(String name) { + nullCheck(name); + lengthCheck(name); + } + + public static void nullCheck(String name) { + if ("".equals(name)) { + throw new IllegalArgumentException("[ERROR]자동차 이름을 입력해주세요."); + } + } + + public static void lengthCheck(String name) { + if (name.length() > MAX_NAME) { + throw new IllegalArgumentException("[ERROR]자동차 이름은 5자 이내여야합니다."); + } + } + +} diff --git "a/racingcar\354\213\244\354\212\265/java/inpututils/InputView.java" "b/racingcar\354\213\244\354\212\265/java/inpututils/InputView.java" new file mode 100644 index 00000000..734dca32 --- /dev/null +++ "b/racingcar\354\213\244\354\212\265/java/inpututils/InputView.java" @@ -0,0 +1,21 @@ +package inpututils; + +import java.util.Scanner; + +public class InputView { + private static final Scanner SCANNER = new Scanner(System.in); + + public static String getCarName() { + System.out.print("경주 할 자동차 이름 : "); + return SCANNER.nextLine(); + } + + public static int getTryNumber() { + System.out.print("시도할 횟수 : "); + try { + return SCANNER.nextInt(); + } catch (NumberFormatException e) { + throw new NumberFormatException("[ERROR] 시도 횟수는 숫자여야 한다."); + } + } +} diff --git "a/racingcar\354\213\244\354\212\265/java/outpututils/OutputView.java" "b/racingcar\354\213\244\354\212\265/java/outpututils/OutputView.java" new file mode 100644 index 00000000..f59dffbb --- /dev/null +++ "b/racingcar\354\213\244\354\212\265/java/outpututils/OutputView.java" @@ -0,0 +1,21 @@ +package outpututils; + +import java.util.ArrayList; + +public class OutputView { + private OutputView() { + } + public static void printCarName(String name) { + System.out.print(name + " : "); + } + + public static void printMove() { + System.out.print("-"); + } + + public static void printWinner(ArrayList winner) { + //TODO:마지막에 , 나오지 않도록 수정 필요 + winner.stream() + .forEach(w -> System.out.print(w + ",")); + } +} diff --git "a/racingcar\354\213\244\354\212\265/java/racingcar/Car.java" "b/racingcar\354\213\244\354\212\265/java/racingcar/Car.java" new file mode 100644 index 00000000..d81e0b13 --- /dev/null +++ "b/racingcar\354\213\244\354\212\265/java/racingcar/Car.java" @@ -0,0 +1,26 @@ +package racingcar; + +import utils.GameUtils; + +public class Car { + private final String name; + private int position = 0; + + public Car(String name) { + InputValidator.nameValidator(name); + this.name = name; + } + + public String getName(){ + return name; + } + + public int plusPosition(){ + return position++; + } + + public int getPosition() { + return position; + } + +} diff --git "a/racingcar\354\213\244\354\212\265/java/racingcar/Cars.java" "b/racingcar\354\213\244\354\212\265/java/racingcar/Cars.java" new file mode 100644 index 00000000..0eb7e6a4 --- /dev/null +++ "b/racingcar\354\213\244\354\212\265/java/racingcar/Cars.java" @@ -0,0 +1,67 @@ +package racingcar; + +import outpututils.OutputView; +import utils.RandomUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class Cars { + private static final int START_NUMBER = 0; + private static final int END_NUMBER = 9; + private static final int BOUNDARY_NUMBER = 4; + private static List carList; + private static ArrayList winner; + + public Cars(List carList) { + this.carList = carList; + } + + public static boolean isMove(int randomNumber) { + if (randomNumber >= BOUNDARY_NUMBER) { + return true; + } + return false; + } + + public static void playGame() { + for (int j = 0; j < carList.size(); j++) { + OutputView.printCarName(carList.get(j).getName()); + + if (isMove(RandomUtils.nextInt(START_NUMBER, END_NUMBER))) { + carList.get(j).plusPosition(); + } + for (int k = 0; k < carList.get(j).getPosition(); k++) { + OutputView.printMove(); + } + System.out.println(); + } + } + + public static int getMax() { + int max = carList.stream() + .mapToInt(Car::getPosition) + .max() + .getAsInt(); + return max; + } + + public static void setWinnerList(int max) { + winner = new ArrayList(); + carList.stream() + .filter(s -> s.getPosition() == max) + .filter(s -> winner.add(s.getName())) + .collect(Collectors.toList()); + } + + public static ArrayList getWinnerList() { + return winner; + } + public static void playGames(int inputCount){ + for (int i = 0; i < inputCount; i++) { + playGame(); + System.out.println(); + } + } +} diff --git "a/racingcar\354\213\244\354\212\265/java/utils/GameUtils.java" "b/racingcar\354\213\244\354\212\265/java/utils/GameUtils.java" new file mode 100644 index 00000000..2d687467 --- /dev/null +++ "b/racingcar\354\213\244\354\212\265/java/utils/GameUtils.java" @@ -0,0 +1,32 @@ +package utils; + +import inpututils.InputView; +import outpututils.OutputView; +import racingcar.Car; +import racingcar.Cars; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class GameUtils { + + public static List makeCarList(String[] splitResult) { + return Arrays.stream(splitResult) + .map(Car::new) + .collect(Collectors.toList()); + } + + public static void run() { + String inputName = InputView.getCarName(); + int inputCount = InputView.getTryNumber(); + String[] splitResult = SplitString.splitString(inputName); + + Cars cars = new Cars(makeCarList(splitResult)); + + Cars.playGames(inputCount); + Cars.setWinnerList(Cars.getMax()); + OutputView.printWinner(Cars.getWinnerList()); + + } +} diff --git "a/racingcar\354\213\244\354\212\265/java/utils/RandomUtils.java" "b/racingcar\354\213\244\354\212\265/java/utils/RandomUtils.java" new file mode 100644 index 00000000..020c8f40 --- /dev/null +++ "b/racingcar\354\213\244\354\212\265/java/utils/RandomUtils.java" @@ -0,0 +1,24 @@ +package utils; + +import java.util.Random; + +public class RandomUtils { + private static final Random RANDOM = new Random(); + + private RandomUtils() { + } + + public static int nextInt(final int startInclusive, final int endInclusive) { + if (startInclusive > endInclusive) { + throw new IllegalArgumentException(); + } + if (startInclusive < 0) { + throw new IllegalArgumentException(); + } + + if (startInclusive == endInclusive) { + return startInclusive; + } + return RANDOM.nextInt(endInclusive - startInclusive + 1) + startInclusive; + } +} diff --git "a/racingcar\354\213\244\354\212\265/java/utils/SplitString.java" "b/racingcar\354\213\244\354\212\265/java/utils/SplitString.java" new file mode 100644 index 00000000..5857afd3 --- /dev/null +++ "b/racingcar\354\213\244\354\212\265/java/utils/SplitString.java" @@ -0,0 +1,11 @@ +package utils; + +public class SplitString { + private static final String BOUNDARY_STRING= ","; + private SplitString() { + } + + public static String[] splitString(String input) { + return input.split(BOUNDARY_STRING); + } +} diff --git "a/racingcar\354\213\244\354\212\265/wrapper/gradle-wrapper.properties" "b/racingcar\354\213\244\354\212\265/wrapper/gradle-wrapper.properties" new file mode 100644 index 00000000..be52383e --- /dev/null +++ "b/racingcar\354\213\244\354\212\265/wrapper/gradle-wrapper.properties" @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git "a/\354\236\220\353\260\224\352\270\260\354\264\210.md" "b/\354\236\220\353\260\224\352\270\260\354\264\210.md" new file mode 100644 index 00000000..608bc7e7 --- /dev/null +++ "b/\354\236\220\353\260\224\352\270\260\354\264\210.md" @@ -0,0 +1,166 @@ +# 2021-Java-Study 10주차 과제 + +## 자바 기초 + +## 컬렉션 프레임 워크(JCF) +> 자바 컬렉션 프레임 워크란 Java에서 데이터를 저장하는 기본적인 자료구조들을 한 곳에 모아 관리하고 편하게 사용하기 위해 제공하는 것을 의미한다. + +![img](./image/img.jpg) + +|인터페이스|구현클래스|특징| +|----------|------|---| +|List|LinkedList
Stack
Vector
ArrayList
|순서가 있는 데이터 집합, 중복 허용| +|Set|HashSet
TreeSet
|순서유지 않는 데이터 집합,중복 허용x| +|Map|HashMap
TreeMap
HashTable
|Key-Value쌍의 데이터 집합으로 키는 중복x, 값은 중복 허용가능| + +### List 인터페이스 +LinkedList: 양방향 포인터 구조, 데이터 삽입/삭제 빈번시 유용, 검색은 ArrayList에 비해 비효율적
+Stack: 한 쪽 끝에서 자료를 넣고 뺄 수 있는 자료구조 +Vector: 동적 크기 배열, 배열과 마찬가지로 index로 배열에 접근 가능, 동기화 되어 있어 한번에 하나의 쓰레드만 벡터 메소드 호출 가능, 멀티 쓰레드 환경 아닌 경우에는 ArrayList를 사용 하는 것이 바람직 할 수 있음
+ArrayList: 단방향 포인터 구조, 데이터에 대한 index 가지며 조회 기능 성능 뛰어남, 데이터 삽입/삭제가 빈번할 경우 비효율적
+ +### Set 인터페이스 +HashSet: 순서 예측 불가능, 해시 알고리즘 사용한 가장 빠른 임의 접근 속도 가짐
+TreeSet: 이진 검색 트리 형태로 데이터 저장, 저장 순서 유지x
+ +### Map 인터페이스 +HashMap: 중복과 순서 허용x, Value에 Null 값 넣을 수 있음
+TreeMap: 키 값이 자연 순서 대로 오름차수 정렬 되어 Key-Value쌍으로 저장. 정렬되어 검색이 빠름
+HashTable: HashMap보다는 느리지만 동기화 지원, Value에 Null값 허용X + + +## Stream의 특징 정리 (map,filter,sorted,distinct,limit,foreach) +``` +ArrayList list = new ArrayList<>(Arrays.asList("Apple","Banana","Apple",Melon","Grape","Strawberry")); +``` + +### map +> 요소들을 특정조건에 해당하는 값으로 변환 +>
요소들을 대,소문자 변형 등 작업 시 사용 + +``` +list.stream().map(s->s.toUpperCase()); +list.stream().map(String::toUpperCase); +``` +이후 collect를 통해 결과를 리턴 받을 수 있다. forEach를 통해 바로 출력도 가능하다. +``` +System.out.println(list.stream().map(s->s.toUpperCase()).collect(Collectors.toList())); //[APPLE, BANANA, APPLE, MELON, GRAPE, STRAWBERRY] +``` +### filter +> 요소들을 조건에 따라 걸러내는 작업 +>
길이 제한, 특정문자 포함 등 작업 시 사용 + +``` +list.stream().filter(t->t.length()>5) +``` +요소 크기가 5보다 큰 것만 걸러내 준다. +``` +System.out.println(list.stream().filter(t->t.length()>5).collect(Collectors.toList())); //[Banana, Strawberry] +``` +### sorted +> 요소들을 정렬해주는 작업 +``` +list.stream().sorted() +``` +리스트의 요소를 정렬해준다. +``` +System.out.println(list.stream().sorted().collect(Collectors.toList())); //[Apple, Apple, Banana, Grape, Melon, Strawberry] +``` +### discinct +> 요소의 중복을 제거해주는 작업 +``` +list.stream().distinct() +``` +리스트의 중복을 제거해준다. +``` +list.stream().distinct().forEach(System.out.println); +// Apple +// Banana +// Melon +// Grape +// Strawberry +``` +### limit +> 어떤 스트림에서 일정 개수만큼 가져와 새로운 스트림을 리턴해주는 작업 +``` +list.stream.limit(3).forEach(System.out.println); +// Apple +// Banana +// Apple +``` +### foreach +> 요소들을 하나씩 출력하는 작업 +``` +list.stream.forEach(System.out.println); +// Apple +// Banana +// Apple +// Melon +// Grape +// Strawberry +``` + +## Collection.forEach와 Stream.forEach 차이 +### Stream 객체 사용 여부 +Collection.forEach의 경우에는 따로 객체를 생성하지 않고 메소드를 호출한다.
+반면에 Stream.forEach는 stream()으로 Stream 객체를 생성해야만 메소드를 호출할 수 있다. + +``` +list.forEach(System.out::println); +list.stream().forEach(Systmem.out::println); +``` + +### Parallel Stream +``` +public void print() { List nums = Arrays.asList(1, 2, 3, 4, 5); + System.out.println("Collection.forEach 출력 시작"); + nums.forEach(System.out::println); + System.out.println("Stream.forEach 출력 시작"); + nums.parallelStream().forEach(System.out::println); } +//Collection.forEach 출력 시작 +//1 +//2 +//3 +//4 +//5 +//Stream.forEach 출력 시작 +//3 +//4 +//1 +//5 +//2 + +출처: https://dundung.tistory.com/247 [DunDung] +``` +ParallelStream으로 생성한 스트림 객체는 여러 스레드에서 스트림을 실행하기에 실행순서가 예측 불가능한 반면 Collection.forEach는 일정한 순서를 보장한다. + +## for문을 stream으로 변환하는 법 + +``` +List list1= Arrays.asList("a", "b", "c", "d", "e"); +List list2 = Arrays.asList("a", "b", "d"); + +//for문 사용해 같은 것만 List에 담으려면 + +List result1 = new ArrayList<>(); + for(String str1 : list1){ + for(String str2 : list2){ + if(str1.equals(str2)){ + result1.add(str1); + } + } + } + for(String str : result1){ + System.out.print(str); + } + +// stream 이용해 같은 것만 List에 담으려면 + List result2 = + list1.stream() + .filter(str -> list2.stream().anyMatch(Predicate.isEqual(str))) + .collect(Collectors.toList()); + + result2.stream().forEach(System.out::print); + +``` +