티스토리 뷰

스프링, 자바

제어문

killog 2020. 11. 28. 12:56
반응형

목표

자바가 제공하는 제어문을 학습하세요.

학습할 것

선택문
반복문

 


제어문

제어문: 코드의 실행 흐름(순서)를 제어하는 구문 ( cf. 순차문 : 코드가 작성된 순서대로 실행되는 구문)

조건문

if 문

간단한 의사 결정 문입니다. 명령문 또는 명령문 블록의 실행 여부를 결정하는 데 사용됩니다. 주어진 조건이 참이면 명령문 블록이 실행되고 그렇지 않으면 명령문 블록을 건너 뜁니다. 조건을 실행하는 동안 조건이 참이면 해당 명령문이 실행되고 나머지 코드는 건너 뜁니다. 어떤 조건도 참이 아니면 마지막 else 문이 실행됩니다.

if(condition)
{
   // If condition is true then this block of statements will be executed
}
else if(condition)
{
   // If condition is true then this block of statements will be executed
}
else 
{
   // If none of condition is true, then this block of statements will be executed
}

선택문 ( switch/case 문 )

다중 if문 대신 사용, 조건문의 일종으로 볼 수 있습니다.

if문을 여러 개 사용하면 실행 속도가 느려지기 때문에 사용합니다.

switch함수의 매개변수에 들어오는 값에 따라 코드를 실행합니다. 즉, 스위치 문은 조건에 기초한 다수의 블록 중 한 블록의 명령문을 실행합니다. switch 문에는 많은 선택 항목이 있으며 각 선택 항목에 대해 다른 작업을 수행 할 수 있습니다.

 

 

  1.  switch 문 표현식은 byte, short, int, long, enum 유형, String 및 Byte, Short, Int 및 Long과 같은 일부 래퍼 유형일 수 있습니다.(단, switch 표현식에서만 wrapper 허용하고, case 에는 wrapper 를 허용하지 않는다.) switch () 대괄호 사이에 변수 또는 표현식을 넣을 수 있습니다  (float 은  개의 부동 소수점 숫자를 비교하는 것은 x와 y의 십진수 등가가 합리적인 정밀도로 동일하게 보일 때 정확하지 않을 수 있어 허용하지 않습니다.)
  2. 케이스 값은 리터럴 또는 상수 여야합니다. 케이스 값 유형은 표현식 유형이어야합니다.
  3. 각 케이스는 고유해야합니다. 중복 케이스 값을 생성하면 컴파일 타임 오류가 발생합니다.
  4. 각 케이스에는 선택적인 break 문 이 있습니다. 스위치 내부에서 명령문 시퀀스를 종료하고 스위치 표현식 다음에 컨트롤을 점프하는 데 사용됩니다.
  5. 어떤 경우에도 break 문을 사용하지 않으면 break  문에 도달 할 때까지 다음 case로 실행이 계속됩니다  .
  6. 스위치 문 케이스에 해당하는 경우가 없으면  default 가 실행됩니다. 기본 케이스에는 break 문이 필요하지 않습니다 .

 

 

 

 

 

https://javagoal.com/switch-statement-java/#1

기본틀

switch(조건식){
     case 값1:
     실행 코드
     break;
     case 값2:
     실행 코드
     break;
     case 값3:
     실행 코드
     break;
     default: case에 해당하는 값이 없을 때 실행할 코드 
      break;        
}
/*
case 값의 개수는 임의로 설정 가능
break : 코드가 실행되다가 break를 만나면,
바로 실행을 중지하고 해당 loop에서 빠져나옴 
*/

여러 case 가 같은 결과 일 경우 

더보기
 switch(variable/expression)
 {
   case value1 :
   case value2 :
   case value3 :
   case value4 :
      // 실행 코드
      break; 
   
   case value5 :
   case value6 :
   case value7 :
   case value8 :
       // 실행 코드
      break; 
    .
    .
    .
    default : 
           // 실행 코드
}

문자 케이스 ( char case )

더보기
public class ExampleOfSwitch
 {  
    public static void main(String[] args)
    {  
         //Declaring a variable for switch expression  
         char alphabet = 'b';  
         switch(alphabet) //Switch expression  
         {  
                //Case statements  
               case 'a': 
               System.out.println("This is character 'a' ");
               break;
               case 'b':
               System.out.println("This is character 'b' ");
               break;
               case 'c':
               System.out.println("This is character 'c' ");
               break;  
                //Default case statement  
               default: System.out.println("Please enter valid input");  
          }  
      }  
}  

중첩 case 를 포함한 경우

더보기

 

switch(variable/expression)
 {
   case value1 :
      // code inside the case value1
      break; // optional
   
   case value2 :
      // code inside the case value2 
      break; // optional
   case value3 : 
   switch(variable/expression)
   {
      case valueOne :
         // code inside the case valueOne 
         break; // optional
   
      case valueTwo :
         // code inside the case valueTwo 
         break; // optional
      .
      .
      .
      default : 
         // code inside the default case .
   }
   .
   .
   .
    default : 
           // code inside the default case .
}

 

 

예시

public class ExampleOfNestedSwitch
{
   public static void main(String[] args)
   {
      //Declaring a variable for switch expression
      int year = 3;
      int marks = 80;

      switch(year) //Switch expression
      {
         //Case statements
         case 1:
         System.out.println("First year students are not eligible for scholarship ");
         break;
         case 2:
         System.out.println("Second year students are not eligible for scholarship");
         break;
         case 3:
         switch(marks)
         {
            case 50:
            System.out.println("You are not eligible for scholarship");
            break;
            case 80:
            System.out.println("Congrats!!!!! you are eligible for scholarship");
            break;
         }
         break;
         //Default case statement
         default: System.out.println("Please enter valid year");
     }
   }
}

예문

public class SwitchTest {
	public static void main(String[] args) {
		int num = 31;

		switch (num % 3) {
			case 0:
				System.out.println(num + "을 3으로 나눈 나머지는 0입니다.");
				break;
			case 1:
				System.out.println(num + "을 3으로 나눈 나머지는 1입니다.");
				break;
			default:
				System.out.println(num+"을 3으로 나눈 나머지는 2입니다.");
				break;	}
	}
}
//31을 3으로 나눈 나머지는 1입니다.
더보기

 

//바이트 코드
????;5

java/lang/Object<init>()V	



java/lang/SystemoutLjava/io/PrintStream;
                                        makeConcatWithConstants(I)Ljava/lang/String;

java/io/PrintStreamprintln(Ljava/lang/String;)V
StackMapTableeLineNumberTablemain([Ljava/lang/String;)V
SourceFileSwitchTest.javaBootstrapMethods$
%&'
   ($java/lang/invoke/StringConcatFactory?(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite*,을 3으로 나눈 나머지는 0입니다,,을 3으로 나눈 나머지는 1입니다.,을 3으로 나눈 나머지는 2입니다.
                                                  InnerClasses1%java/lang/invoke???????? /dles$Lookup3java/lang/invoke/MethodHandlesLookup!?	K<?8)?
;
J>      ? 
           !"#)#+#-/
024%     

break 문의  필요성

switch 문을 빠져나오지 못하고 매칭 조건 이후의 계속  조건을 실행하고 default 까지 가게되는 결론이 됩니다. (원하는 결과가 나오지 않습니다,)

 break 문 이 없으면 default case를 포함한 모든 case를 실행합니다 . 폴 스루(fall-through) 라고  합니다.

break문 

java의break 문은 프로그래머가 실행 순서를 중단하기 위해 매우 일반적으로 사용합니다.break 문은루프와 switch 문에 사용됩니다.

더보기
https://javagoal.com/break-statement-in-java/

continue문

 

더보기
https://javagoal.com/continue-statement-in-java/

 

반복문

자바의 반복문은 조건이 참이 될 때까지 블록을 반복적으로 실행하는 데 사용됩니다. 루프를 사용하면 코드를 여러 번 또는 조건을 만족할 때까지 실행할 수 있습니다.

https://javagoal.com/loops-in-java/

for 문

사용자가 코드 블록을 여러 번 실행하려는 경우 사용합니다. 반복 횟수가 고정되어 있는 것이 특징입니다. for ( ;; ) 의경우는 무제한 반복횟수라고 볼 수 있습니다. )For 루프는 초기화, 조건, for 루프 본문, 증가 / 감소의 네 부분으로 구성됩니다.

1. 초기화
2. 조건
3. for 루프 본문
4. 증가 / 감소

for(initialization; condition; increment/decrement)
{
   // Body of for loop
}

1. 초기화 : 초기화는 루프의 첫 번째 부분이며 한 번만 발생합니다. 루프의 시작점을 표시합니다. 여기에서 변수를 선언 및 초기화하거나 이미 초기화 된 변수를 사용할 수 있습니다.
2. 조건 : 조건은 루프의 두 번째 부분이며 부울 값을 true 또는 false로 반환해야하는 조건을 제공 / 작성해야합니다. 루프의 상태를 테스트하기 위해 매번 실행됩니다. 조건이 거짓이 될 때까지 실행을 계속합니다.
3. for 루프의 본문 : 조건 참을 평가 한 후 매번 실행되는 코드 블록을 포함합니다.
4. 증가 / 감소 : 변수의 인덱스 값을 업데이트하는데 사용됩니다.

https://javagoal.com/for-loop-java/

while 문

루프 상태  조건이 만족 될 때까지 허용 코드가 반복하여 실행됩니다. 반복 횟수가 고정되지 않은 경우 while 루프 를 사용하는 것이 좋습니다  . 입력 제어 루프 라고도 합니다.

while(condition)
{
   // Body of while loop
}
  • true를 반환 하면 while 루프 의 본문 이 실행됩니다. while 루프 의 본문 에서 명령문은 다음 반복을 위해 처리되는 변수에 대한 업데이트 값을 포함합니다.
  • false를 반환하면 루프가 종료되어 수명주기의 끝을 표시합니다.
  • ( while 루프 조건에서 true를 전달하면. 그러면 무한 루프가됩니다. )

https://javagoal.com/while-loop-java/

do-while 문

while 루프와 거의 유사합니다. 루프 본문을 실행 한 후 조건을 확인하는 유일한 차이점이있습니다.  따라서, 조건에 관계 없이 적어도 한번 이상 반복문을 돈다는 특징을 가집니다. Exit Control Loop 라고도  합니다. 

do
{
   // Body of loop
} While(condition);

https://javagoal.com/do-while-loop-in-java/

for each 문

for each는 J2SE 5.0 부터 추가되었다. for each 라는 키워드가 따로 있는 것은 아니고 동일한 for를 이용한다. 하지만 조건식 부분이 조금 다르다. 보통 다른 언어에서 for each 라고 많이 하므로 자바에서도 보통 for each문이라고 말한다.

단, foreach문은 따로 반복회수를 명시적으로 주는 것이 불가능하고, 1스탭씩 순차적으로 반복될때만 사용가능하다는 제약이 있다.

 

for (변수타입 변수명 : 루프를 돌릴 객체) {
    // 실행 코드
}

루프를 돌릴 객체로는 루프를 돌릴수 있는 형태인 Array나 Collections가 가능하고  Iterable<E>를 상속받은 객체또한 가능하다.

예시

String[] temp = { "귤", "감", "토마토" };
for (String e : temp) {
    System.out.println(e);
}

// 기존 for 문
for (int i = 0; i < temp .length; i++) { 
    System.out.println(temp[i]);
}

 

( forEach와 for each 의 차이점은? 이라는 재밌는 포스팅을 발견했는데 재밌다. 머나먼 자바의 길.. (아련아련) namocom.tistory.com/754 )

 


과제 0. JUnit 5 학습하세요.

  • 인텔리J, 이클립스, VS Code에서 JUnit 5로 테스트 코드 작성하는 방법에 익숙해 질 것.
  • 이미 JUnit 알고 계신분들은 다른 것 아무거나!

JUnit 은 Java 에코 시스템에서 가장 인기있는 단위 테스트 프레임 워크 중 하나입니다. JUnit 5 버전에는 Java 8 이상의 새로운 기능을 지원 하고 다양한 스타일의 테스트를 가능하게 하는 것을 목표로하는 흥미로운 혁신이 많이 포함되어 있습니다 .

 

JUnit 5.x.0 설정 

 pom.xml에 다음 종속성을 추가해야합니다 .

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.1.0</version>
    <scope>test</scope>
</dependency>

이 버전 이 작동하려면 Java 8  필요합니다 .

또한 IntelliJ뿐만 아니라 Eclipse의 JUnit 플랫폼에서 단위 테스트를 실행하는 직접 지원이 있습니다. 물론 Maven Test 목표를 사용하여 테스트를 실행할 수도 있습니다.

반면 IntelliJ는 기본적으로 JUnit 5를 지원합니다. 따라서 IntelliJ에서 JUnit 5를 실행하는 것은 매우 간단합니다. 오른쪽 클릭 –> 실행 또는 Ctrl-Shift-F10 만 있으면됩니다.

3. 아키텍처

JUnit 5는 세 가지 하위 프로젝트의 여러 모듈로 구성됩니다.

3.1. JUnit 플랫폼

플랫폼은 JVM에서 테스트 프레임 워크를 시작하는 역할을합니다. JUnit과 빌드 도구와 같은 클라이언트 간의 안정적이고 강력한 인터페이스를 정의합니다.

최종 목표는 클라이언트가 테스트를 발견하고 실행할 때 JUnit과 쉽게 통합되는 방법입니다.

또한 JUnit 플랫폼에서 실행되는 테스트 프레임 워크를 개발하기위한 TestEngine API를 정의합니다 . 이를 통해 사용자 정의 TestEngine을 구현하여 타사 테스트 라이브러리를 JUnit에 직접 플러그인 할 수 있습니다.

3.2. JUnit 목성

이 모듈에는 JUnit 5에서 테스트를 작성하기위한 새로운 프로그래밍 및 확장 모델이 포함되어 있습니다. JUnit 4와 비교 한 새로운 주석은 다음과 같습니다.

  • @TestFactory – 동적 테스트를위한 테스트 팩토리 인 메소드를 나타냅니다.
  • @DisplayName – 테스트 클래스 또는 테스트 메서드에 대한 사용자 지정 표시 이름을 정의합니다.
  • @Nested – 주석이 달린 클래스가 중첩 된 비 정적 테스트 클래스임을 나타냅니다.
  • @Tag – 테스트 필터링을위한 태그 선언
  • @ExtendWith – 사용자 지정 확장을 등록하는 데 사용됩니다.
  • @BeforeEach – 주석이 달린 메소드가 각 테스트 메소드 이전에 실행됨을 나타냅니다 (이전 @Before ).(여러번 비포)
  • @AfterEach – 각 테스트 메서드 (이전에는 @After ) 후에 주석이 추가 된 메서드가 실행됨을 나타냅니다.
  • @BeforeAll – 주석이 추가 된 메서드가 현재 클래스의 모든 테스트 메서드보다 먼저 실행됨을 나타냅니다 (이전 @BeforeClass ).(한번 통합전으로 전)
  • @AfterAll – 현재 클래스 (이전의 @AfterClass )의 모든 테스트 메서드 후에 주석이 추가 된 메서드가 실행됨을 나타냅니다.
  • @Disable – 테스트 클래스 또는 메서드를 비활성화하는 데 사용됩니다 (이전에는 @Ignore ).

3.3. JUnit 빈티지

JUnit 5 플랫폼에서 JUnit 3 및 JUnit 4 기반 테스트 실행을 지원합니다.

 

4. 기본 주석

4.1. @BeforeAll  @BeforeEach

다음은 주요 테스트 케이스 전에 실행되는 간단한 코드의 예입니다.

@BeforeAll
static void setup() {
    log.info("@BeforeAll - executes once before all test methods in this class");
}
 
@BeforeEach
void init() {
    log.info("@BeforeEach - executes before each test method in this class");
}

주의해야 할 중요한 것은 @BeforeAll 주석 이있는 메서드는 정적이어야한다는 것입니다. 그렇지 않으면 코드가 컴파일되지 않습니다.

 

 

4.2. @DisplayName  @Disabled

@DisplayName("Single test successful")
@Test
void testSingleSuccessTest() {
    log.info("Success");
}
 
@Test
@Disabled("Not implemented yet")
void testShowSomething() {
}

보시다시피 새 주석을 사용하여 표시 이름을 변경하거나 주석으로 메서드를 비활성화 할 수 있습니다.

4.3. @AfterEach  @AfterAll

마지막으로 테스트 실행 후 작업에 연결된 메서드에 대해 살펴 보겠습니다.

@AfterEach
void tearDown() {
    log.info("@AfterEach - executed after each test method.");
}
 
@AfterAll
static void done() {
    log.info("@AfterAll - executed after all test methods.");
}

@AfterAll 이있는 메서드 도 정적 메서드 여야합니다

 

5. 주장과 가정

JUnit 5는 Java 8의 새로운 기능, 특히 람다 표현식을 최대한 활용하려고합니다.

5.1. assertion

assertion이 org.junit.jupiter.api.Assertions 로 이동 되었으며 크게 개선되었습니다. 앞서 언급했듯이 이제 assertion에서 람다를 사용할 수 있습니다.

@Test
void lambdaExpressions() {
    assertTrue(Stream.of(1, 2, 3)
      .stream()
      .mapToInt(i -> i)
      .sum() > 5, () -> "Sum should be greater than 5");
}

MultipleFailuresError로 그룹 내에서 실패한 주장을보고하는 assertAll () 을 사용 하여 주장을 그룹화 할 수도 있습니다 .즉, 오류의 정확한 위치를 정확히 찾을 수 있으므로 더 복잡한 주장을하는 것이 더 안전합니다.

 @Test
 void groupAssertions() {
     int[] numbers = {0, 1, 2, 3, 4};
     assertAll("numbers",
         () -> assertEquals(numbers[0], 1),
         () -> assertEquals(numbers[3], 3),
         () -> assertEquals(numbers[4], 1)
     );
 }

5.2. 가정

특정 조건이 충족되는 경우에만 테스트를 실행하는 데 가정이 사용됩니다. 이는 일반적으로 테스트를 제대로 실행하는 데 필요하지만 테스트 대상과 직접 관련이없는 외부 조건에 사용됩니다.

가정은 assumeTrue () , assumeFalse ()  assumingThat ()으로 선언 할 수 있습니다 .가정이 실패하면 TestAbortedException 이 발생하고 테스트를 건너 뜁니다.

@Test
void trueAssumption() {
    assumeTrue(5 > 1);
    assertEquals(5 + 2, 7);
}
 
@Test
void falseAssumption() {
    assumeFalse(5 < 1);
    assertEquals(5 + 2, 7);
}
 
@Test
void assumptionThat() {
    String someString = "Just a string";
    assumingThat(
        someString.equals("Just a string"),
        () -> assertEquals(2 + 2, 4)
    );
}

6. 예외 테스트

JUnit 5에는 두 가지 예외 테스트 방법이 있습니다. 둘 다 assertThrows () 메소드를 사용하여 구현할 수 있습니다 .

@Test
void shouldThrowException() {
    Throwable exception = assertThrows(UnsupportedOperationException.class, () -> {
      throw new UnsupportedOperationException("Not supported");
    });
    assertEquals(exception.getMessage(), "Not supported");
}
 
@Test
void assertThrowsException() {
    String str = null;
    assertThrows(IllegalArgumentException.class, () -> {
      Integer.valueOf(str);
    });
}

7. Test Suites

JUnit 5의 새로운 기능을 계속하기 위해 test suites에서 여러 테스트 클래스를 집계하는 개념을 파악하여 함께 실행할 수 있습니다. JUnit 5는 @SelectPackages  @SelectClasses 라는 두 가지 주석을 제공 하여 test suites를 만듭니다.

이 초기 단계에서 대부분의 IDE는 이러한 기능을 지원하지 않습니다.

첫 번째를 살펴 보겠습니다.

@RunWith(JUnitPlatform.class)
@SelectPackages("com.baeldung")
public class AllUnitTest {}

@SelectPackage test suites를 실행할 때 선택할 패키지 이름을 지정하는 데 사용됩니다. 이 예에서는 모든 테스트를 실행합니다. 두 번째 주석 @SelectClasses test suites를 실행할 때 선택할 클래스를 지정하는 데 사용됩니다.

@RunWith(JUnitPlatform.class)
@SelectClasses({AssertionTest.class, AssumptionTest.class, ExceptionTest.class})
public class AllUnitTest {}

예를 들어 위의 클래스는 세 개의 테스트 클래스를 포함하는 스위트를 만듭니다. 수업이 하나의 패키지에있을 필요는 없습니다.

 

과제 1. live-study 대시 보드를 만드는 코드를 작성하세요.

  • 깃헙 이슈 1번부터 18번까지 댓글을 순회하며 댓글을 남긴 사용자를 체크 할 것.
  • 참여율을 계산하세요. 총 18회에 중에 몇 %를 참여했는지 소숫점 두자리가지 보여줄 것.
  • Github 자바 라이브러리를 사용하면 편리합니다.
  • 깃헙 API를 익명으로 호출하는데 제한이 있기 때문에 본인의 깃헙 프로젝트에 이슈를 만들고 테스트를 하시면 더 자주 테스트할 수 있습니다.

github.com/KilJaeeun/checkIssueReplyUser

import org.kohsuke.github.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import static org.antlr.runtime.misc.Stats.sum;

public class CheckIssueReplyUser {
    public static void main(String[] args) throws IOException {
        //사용자 이름 및 암호를 통해 연결
        String my_personal_token = "abcde";
        GitHub github = new GitHubBuilder().withOAuthToken(my_personal_token).build();
        // 깃헙 레포 연결
        GHRepository ghRepositor = github.getRepository("helloTestRepo");

        // 참여자 저장소 생성
        Map<String, int[]> participantHashMap = new HashMap<>();
        // 참여여부 체크
        for (int issueNum = 1; issueNum < 19; issueNum++) {
            GHIssue ghIssue = ghRepositor.getIssue(issueNum);
            PagedIterable<GHIssueComment> ghIssueComments = ghIssue.listComments();
            for (GHIssueComment ghIssueComment : ghIssueComments) {
                String participant = ghIssueComment.getUser().getName();
                if (participantHashMap.containsKey(participant)) {

                    int[] assignments = participantHashMap.get(participant);
                    assignments[issueNum] = 1;
                } else {

                    int[] assignments = new int[19];// 초기값 0
                    assignments[issueNum] = 1;
                    participantHashMap.put(participant, assignments);


                }
            }

        }
        // 참여자 전체 정보 출력
        participantHashMap.forEach((key, value) -> {
            float countPercent = (sum(value) * 100) / 18;
            System.out.print("참여자명: " + key);
            System.out.println(", 참여율: " + String.format("%.2f", countPercent) + "%");
        });

    }


}

과제 2. LinkedList를 구현하세요.

  • LinkedList에 대해 공부하세요.
  • 정수를 저장하는 ListNode 클래스를 구현하세요.
  • ListNode add(ListNode head, ListNode nodeToAdd, int position)를 구현하세요.
  • ListNode remove(ListNode head, int positionToRemove)를 구현하세요.
  • boolean contains(ListNode head, ListNode nodeTocheck)를 구현하세요.

Linked List는 Array List와는 다르게 엘리먼트와 엘리먼트 간의 연결(link)을 이용해서 리스트를 구현한 것을 의미합니다. 

  노드가 데이터와 포인터를 가지고 한 줄로 연결되어 있는 방식으로 데이터를 저장하는 자료 구조입니다. 이름에서 말하듯이 데이터를 담고 있는 노드들이 연결되어 있는데, 노드의 포인터가 다음이나 이전의 노드와의 연결을 담당하게 됩니다.

 

연결 리스트는 늘어선 노드의 중간지점에서도 자료의 추가와 삭제가 O(1)의 시간에 가능하다는 장점을 가집니다. 그러나 배열이나 트리 구조와는 달리 특정 위치의 데이터를 검색해 내는데에는 O(n)의 시간이 걸리는 단점도 갖고 있습니다.

https://opentutorials.org/module/1335/8821

 

https://en.wikipedia.org/wiki/Linked_list   ( 노드의 인풋 과정)

 

 

package study.whiteship;

public class Main {
  interface LinkedList {
    ListNode add(ListNode head, ListNode nodeToAdd, int position);

    void printList(ListNode head);

    ListNode remove(ListNode head, int positionToRemove);

    boolean contains(ListNode head, ListNode nodeTocheck);
  }

  static class LinkedListImpl implements LinkedList {

    public void printList(ListNode head) {
      while (head != null) {
        System.out.println(head.data);
        head = head.next;
      }
    }

    public int size(ListNode head) {
      ListNode node = head;
      int size = 1;
      while (node.next != null) {
        node = node.next;
        size++;
      }
      return size;
    }

    public ListNode add(ListNode head, ListNode nodeToAdd, int position) {

      ListNode node = head;
      if (position == 0) {
        if (head == null) {
          return nodeToAdd;
        }
        // 노드를 생성한다.
        ListNode add = nodeToAdd;
        // 새로운 노드의 다음 노드로 헤드를 지정한다.
        add.next = head;
        // 헤드로 새로운 노드를 지정한다.
        head = add;
        return head;
      }

      for (int i = 0; i < position - 1; i++) {
        node = node.next;
      }
      nodeToAdd.next = node.next;
      node.next = nodeToAdd;
      return head;
    }

    public boolean contains(ListNode head, ListNode nodeTocheck) {
      while (head != null) {

        if (head.data == nodeTocheck.data) {
          return true;
        }
        head = head.next;
      }
      return false;
    }

    public ListNode remove(ListNode head, int positionToRemove) {
      ListNode node = head;
      if (positionToRemove == 0) {
        head = head.next;
      } else {
        for (int i = 0; i < positionToRemove - 1; i++) {
          node = node.next;
        }
        ListNode delNode = node.next;
        node.next = node.next.next;
      }
      return head;
    }
  }

  static class ListNode {
    private int data;
    private ListNode next;

    public ListNode(int input) {
      data = input;
      next = null;
    }

    @Override
    public String toString() {
      return String.valueOf(data);
    }
  }

  public static void main(String[] args) {
    LinkedList numbers = new LinkedListImpl();
    // 시작에 추가
    ListNode head = null;
    for (int i = 0; i < 10; i++) {
      head = numbers.add(head, new ListNode(i), i); // 특정 포지션 추가
    }
    head = numbers.remove(head, 0);
    head = numbers.remove(head, 1);
    head = numbers.remove(head, 2);
    System.out.println(numbers.contains(head, new ListNode(5)));
    System.out.println(numbers.contains(head, new ListNode(2)));
    numbers.printList(head);
  }
}

과제 3. Stack을 구현하세요.

  • int 배열을 사용해서 정수를 저장하는 Stack을 구현하세요.
  • void push(int data)를 구현하세요.
  • int pop()을 구현하세요.
package study.whiteship;

public class Main {
  interface Stack {
    boolean isEmpty();

    boolean isFull();

    void push(int data);

    void printStack();

    int pop();
  }

  public static class ArrayStack implements Stack {
    private int top;
    private int stackSize;
    private int stackArr[];

    // 스택을 생성하는 생성자
    public ArrayStack(int stackSize) {
      top = -1; // 스택 포인터 초기화
      this.stackSize = stackSize; // 스택 사이즈 설정
      stackArr = new int[stackSize]; // 스택 배열 생성
    }

    @Override
    public boolean isEmpty() {
      return top == -1;
    }

    @Override
    public boolean isFull() {
      return top == stackSize - 1;
    }

    @Override
    public void push(int data) {

      stackArr[++top] = data;
    }

    @Override
    public void printStack() {
      System.out.println("--printStack start--");
      for (int i = 0; i <= top; i++) {
        int i1 = stackArr[i];
        System.out.println(i1);
      }
      System.out.println("--printStack end--");
    }

    @Override
    public int pop() {
      if (top == -1) {
        System.out.println("Empty! you can't pop");
        return 0;
      } else {
        int answer = stackArr[top];
        top--;
        return answer;
      }
    }
  }

  public static void main(String[] args) {
    int stackSize = 5;
    ArrayStack arrStack = new ArrayStack(stackSize);
    arrStack.push(1);
    arrStack.push(2);
    arrStack.printStack();

    arrStack.push(3);
    arrStack.printStack();

    arrStack.pop();
    arrStack.printStack();

    arrStack.pop();
    arrStack.printStack();
  }
}

과제 4. 앞서 만든 ListNode를 사용해서 Stack을 구현하세요.

  • ListNode head를 가지고 있는 ListNodeStack 클래스를 구현하세요.
  • void push(int data)를 구현하세요.
  • int pop()을 구현하세요.
package study.whiteship;

public class Main {

  static class ListNodeStack {
    // 리스트 데이터 전체 출력 메소드
    public void printList(ListNode head) {
      while (head != null) {
        System.out.println(head.data);
        head = head.next;
      }
    }
    // 뒤에 추가
    public ListNode push(ListNode head, ListNode nodeToAdd) {
      ListNode node = head;
      ListNode newNode = nodeToAdd;

      if (node == null) {
        return newNode;
      }
      while (node.next != null) {
        node = node.next;
      }
      node.next = newNode;
      return head;
    }

    // 노드 사이즈 찾는 메소드
    public int size(ListNode head) {
      ListNode node = head;
      int size = 1;
      while (node.next != null) {
        node = node.next;
        size++;
      }
      return size;
    }
    // 특정 위치의 노드를 삭제하는 메소드
    public ListNode pop(ListNode head) {
      int positionToRemove = size(head) - 1;
      ListNode node = head;
      ListNode delNode;
      if (positionToRemove == 0) {
        head = head.next;
        delNode = head;
      } else {
        for (int i = 0; i < positionToRemove - 1; i++) {
          node = node.next;
        }
        delNode = node.next;
        node.next = node.next.next;
      }
      return delNode;
    }
  }

  static class ListNode {
    private int data;
    private ListNode next;

    public ListNode(int input) {
      data = input;
      next = null;
    }

    @Override
    public String toString() {
      return String.valueOf(data);
    }
  }

  public static void main(String[] args) {
    ListNodeStack stack = new ListNodeStack();
    // 시작에 추가
    ListNode head = null;
    for (int k = 10; k < 15; k++) {
      head = stack.push(head, new ListNode(k)); // 뒤에 추가
    }
    stack.printList(head); 
    System.out.println("--");
    System.out.println(stack.pop(head));
    System.out.println("--");
    stack.printList(head); 
  }
}

 


참고문헌

ko.wikipedia.org/wiki/%EC%97%B0%EA%B2%B0_%EB%A6%AC%EC%8A%A4%ED%8A%B8

www.baeldung.com/junit-5

gmlwjd9405.github.io/2019/11/26/junit5-guide-basic.html

blog.outsider.ne.kr/271

javagoal.com/if-else-ladder-in-java/

wikidocs.net/211

pathas.tistory.com/109?category=880477

freestrokes.tistory.com/82

반응형

'스프링, 자바' 카테고리의 다른 글

스프링, 직접 response 하는 법  (0) 2020.12.04
why we use spring?  (0) 2020.12.02
3주차 과제: 연산자 (백기선 라이브 스터디 3주차 )  (0) 2020.11.22
mvc 아키텍처  (0) 2020.11.18
mocMvc Controller Test  (0) 2020.11.18
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함