여러 테이블의 값을 조회할 때 뷰 외에도 사용할 수 있는 방법이 뭐가 있을까 하다가

여러 시행착오를 겪어보았다.

여기에서 foreach 를 이중으로 써보니 jsp에서 출력이 제곱으로 되는 문제가 있었고,

아직 jstl 문법에서 var와 item 정도 밖에 몰랐던 수준에서는 방법이 보이지 않아

이런저런 뻘짓 끝에 varStatus 라는 문법을 알게 되었다.

(실은 문서도 제대로 찾아보지 않고 학원에서 배운대로만 활용해보려 했던 잘못이기도 하다. 심화해서 작업을 해볼 생각이었으면 조금 장벽에 부딪혔을 때 바로 문서를 찾아보자고 다시 다짐해본다...)

foreach 문에 varStatus를 이용한다면 다음과 같이 이용할 수 있다.

<c:foreach items="${배열이름}" var="별칭" varStatus="상태용 변수">
 
	// 반복해서 표시할 내용 혹은 반복할 구문
 
</c:foreach>

// 배열이름에는 jsp 등에서 setAttribute 등으로 전달한 배열도 활용할 수 있다.
// 별칭은 반복 구문 안에서 사용할 변수의 이름을 별칭으로 지정해주는 형태이다.
/** 
	상태용 변수라는 말은 다양한 방식으로 활용할 수 있다.
    varStatus 뒤에 올 수 있는 값으로는 foreach에 사용가능한 대부분의 값이 올 수 있다.
    예를 들어 current index count begin end step 등을 말한다.
    
    표현 방식은 
    ${상태용 변수.index}
    이런 식으로 활용이 가능하다. 조금만 더 응용해보자면
    한번의 반복문 안에서 같은 인덱스를 공유하는 다른 배열을 처리할 수도 있다.

	ArrayList의 형식을 빌려서 세팅된 배열이 2개 이상 있다고 가정하고
    아래의 코드를 만들어볼 생각이다.
*/


// 예시 구문, 모든 배열은 ArrayList의 형식
// 게시물에 대한 정보를 담은 boardList
// 멤버들의 값이 담긴 membersList,
// 게시물에 대한 덧글들의 관계정보가 담긴 memberReplyList가 세션에 전달되었다고 치자.

<table>
<c:foreach items="${boardList}" var="boardVO" varStatus="status">
	// 게시물의 번호와
    // 그 번호 게시물에 작성자 해당하는 유저의 닉네임
    // 사람들이 그 번호 게시물에 대해 달은 전체 덧글의 수를
    // 같은 인덱스를 공유하며 한번의 반복으로 표현할 수 있습니다.
	<tr>
    	<td>${boardVO.boardNumber}</td>
        <td>
        	${membersList[status.index].nickname}
        	${memberReplyList[status.index].count}
        </td>
    </tr>
</c:foreach>
</table>

 

※ 본 포스팅은 저의 공부 과정을 기록하기 위한 용입니다.

해당 문제의 정답을 기재해둔 것은 아니니 참고하여주시기 바랍니다.

 문제

문제 설명

외과의사 머쓱이는 응급실에 온 환자의 응급도를 기준으로 진료 순서를 정하려고 합니다. 정수 배열 emergency가 매개변수로 주어질 때 응급도가 높은 순서대로 진료 순서를 정한 배열을 return하도록 solution 함수를 완성해주세요.


제한사항
  • 중복된 원소는 없습니다.
  • 1 ≤ emergency의 길이 ≤ 10
  • 1 ≤ emergency의 원소 ≤ 100

 풀이

위의 문제를 JAVA 로 풀기 위해서는 두개의 배열을 이용해서 이중반복문을 통해 풀면 된다.

class Solution {
    public int[] solution(int[] emergency) {
        // int[] answer = new int[emergency.length];
        int el = emergency.length;
		
		int[] answer = new int[el];
		int[] emergencyT = new int[el];
        int count = 1;  // 카운트가 계속 늘어날 함수
        int temp = 0;   // 최고값 비교를 위한 임시값을 저장하는 함수
        
//        answer[0] = 2;
//        answer[1] = 4;
//        answer[2] = 3;
//        answer[3] = 5;
//        answer[4] = 1;
        
        // 만약에 emergencyT 라는 배열이 있다고 치면
        // emergencyT라는 배열은 내림차순이라고 해보자. 그렇다면
        // int[] emergencyT = {100, 30, 23, 10, 6}으로 나온다.
        // 그렇다면 반복문을 돌면서 두 배열의 값이 같을 때 새로 만든 배열의 인덱스값에 +1을 해주면 되지 않을까?
        // 그렇다면 바로 시작해보자.
        
        // 일단 임시 배열에 값을 복사해준다.
        for(int i = 0; i<el; i++) emergencyT[i] = emergency[i];
        
        // 임시배열을 내림차순으로 바꿔준다.
        for(int i = 0; i<el; i++) {
        	for(int j = i+1; j<el; j++) {
        		if( emergencyT[i]<emergencyT[j] ) {
        			int t = emergencyT[i];
        			emergencyT[i] = emergencyT[j];
        			emergencyT[j] = t;
        		}
        	}
        }
        
        // 정렬까지 다 끝났으므로 임시배열과 원래 배열을 이중반복문으로 돌리면서 answer에 값을 넣는다.
        for(int i = 0; i<el; i++) {
        	for(int j = 0; j<el; j++) {
        		if(emergency[i] == emergencyT[j]) {
        			answer[i] = j+1;
        		}
        	}
        	
        }
        
         return answer;
}
    
}

 

주의할 점은 배열의 인덱스값은 0부터 시작이므로

1만 더해서 숫자를 맞춰주면 된다.

결국 응급도라는건 내림차순으로 정렬했을 때의 인덱스값 + 1이다.

※ 저의 풀이는 정답이 아니며 저의 학습 과정을 남기는 목적으로 제작하는 포스팅입니다.

 문제

연속된 세 개의 정수를 더해 12가 되는 경우는 3, 4, 5입니다. 두 정수 num과 total이 주어집니다. 연속된 수 num개를 더한 값이 total이 될 때, 정수 배열을 오름차순으로 담아 return하도록 solution함수를 완성해보세요.


제한사항

  • 1 ≤ num ≤ 100
  • 0 ≤ total ≤ 1000
  • num개의 연속된 수를 더하여 total이 될 수 없는 테스트 케이스는 없습니다.

 

 풀이

 

일단 로직이 머리속 계산만으로는 되지 않아서 무식한 방법을 사용했다.

 

answer[0] 
answer[1] = answer[0] + 1
answer[2] = answer[1] + 1
answer[3] = answer[2] + 1
...
answer[num] = answer[num-1]+1 = answer[0]+num-1

이라는 식으로 도식화를 해보니 팩토리알이 떠올랐다.


        
if num==8 total==12
만약에 num8 이라 8개의 인덱스가 생성 되었다면
[1 2 3 4 5 6 7 8] (여기 있는 숫자는 예시이고 아직 배열에 넣지도 않았다.)
로 만들어질 수 있겠다.

결론은
(num)의 ! 값을 total로 뺀 값을 num 으로 나눈 몫만큼 모든 항목을 빼주면 된다.
근데 여기서 우리는 위의 배열을 바로 만들지 않아도 된다.
정확히는 1 2 3 4 5 6 7 8의 값을 생각하지 않아도 된다
이미 1을 베이스로 한 상황이었기 때문에 배열의 시작값만 만들어주면된다.


그 말은 
answer[0] = 1 - 위에서 구한 값만 먼저 계산해내면 되고

answer[1] 은 1을 더하고... 이 과정에서만 for문을 주면 된다.

        
만약에
num 3  total 12 라면
배열은  [1 , 2 , 3]이라고 가정하고 (배열의 시작값을 언제나 1로 시작한다는 뜻이다.
3! 는 6이 나온다. total이 12이기 때문에 6-12=-6이 나온다.
여기서 -6을 3으로 나누고 그 값으로 빼기 때문에
그러면 우리는 answer[0]==1에 1-(-6/3) = 1-(-2) = 1+2로 맞게 실행이 될 것이다.

이제 로직은 간단해졌으니 다시 코드화시켜보자.

class Solution {
    public int[] solution(int num, int total) {
        int[] answer = new int[num];    // num만큼 answer의 배열을 선언해줍니다.
        
        int temp = 0;
        int fact = 0;
        
        // (num 값의 팩토리얼을 구해서 fact 라는 임시 변수에 넣습니다.)
        for(int i = 1; i<=num; i++){
            fact+=i;
        }
        
        temp = 1 - (fact-total)/num;
        
        for(int i = 0; i<num; i++){
            answer[i] = temp + i;
        }
        
        return answer;
    }
}

※ 본 풀이는 정답이 아니며 공부용 기록입니다.

 문제

등차수열 혹은 등비수열 common이 매개변수로 주어질 때, 마지막 원소 다음으로 올 숫자를 return 하도록 solution 함수를 완성해보세요.


제한사항

  • 2 < common의 길이 < 1,000
  • -1,000 < common의 원소 < 2,000
  • 등차수열 혹은 등비수열이 아닌 경우는 없습니다.
  • 공비가 0인 경우는 없습니다.

 풀이

class Solution {
    public int solution(int[] common) {
        int answer = 0;
        int temp = 0;
        // 1번째 인덱스를 0번째 인덱스로 뺀 값과 
        // 2번째 인덱스를 1번째 인덱스로 뺀 값이 같을 경우 - 등차수열
        if(common[1]-common[0] == common[2]-common[1]){
            temp = common[1]-common[0];
            answer = common[common.length-1] + temp;
        }
        // 1번째 인덱스로 0번째 인덱스를 / 한 값과 
        // 2번째 인덱스를 1번째 인덱스로 / 한 값이 같으면 등비수열
        else if(common[1]/common[0] == common[2]/common[1] && common[0]>0){
            temp = common[2]/common[1];
            answer = common[common.length-1] * temp;
        }
        else if(common[1]/common[0] == common[2]/common[1] && common[0]<0){
            temp = common[2]/common[1];
            answer = common[common.length-1] * temp;
        }
        return answer;
    }
}

경로를 맞게 넣었다고 생각했는데 계속 오류가 나는 상황

 

java.io.FileNotFoundException(지정된 경로를 찾을 수 없습니다)

 

 

사진 파일을 인풋에 담아서 직접 자바에서 구현시킬 때는 ../폴더/파일이름 이런 식으로 경로를 적어주어야지만 구현이 되었는데
같은 식으로 코드를 짜니 음악이 계속해서 재생이 되지 않는 상황에 봉착했다.

보통 위와 같은 메세지가 떴을 때는

1. 파일 이름이나 경로 스펠링 체크

2. System.out.println(new File("파일 경로").getAbsolutePath()); 를 통한 절대 경로 획득

3. src 안에 잘 넣었는지 확인하기

등이 있는 것으로 아는데 3가지 상황에 다 해당되지 않으니 환장할 노릇이었다.

/폴더/파일이름

./폴더/파일이름

등등 할 수 있는 선택지를 다 바꿔서 해봐도 응답하지 않았다...

그러다 src부터 경로를 복사해서

src/music/파일이름.wav

이런 식으로 경로를 설정하니 잘 동작하였다.

사진과 음악의 경로 설정이 다르다는걸 확인했다.



JAVA로 게임을 만드는 예제를 따라해서 만들어보던 중

위의 에러에 만나서 구글로 해결을 해보려 했지만 모든 방법을 따라해보아도 해결이 되지 않았다.

나왔던 에러의 전문은 다음과 같다

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.net.URL.toExternalForm()" because "location" is null
	at java.desktop/javax.swing.ImageIcon.<init>(ImageIcon.java:234)
	at Dynamic_Beat/dynamic_beat_2.DynamicBeat.<init>(DynamicBeat.java:25)
	at Dynamic_Beat/dynamic_beat_2.Main.main(Main.java:10)

찾아본 결과로 미루어 봤을 때 위의 문구는

1. 파일의 경로를 잘못 설정하거나,

2. 파일 링크가 되지 않는 상태이거나(연결시켜야 하는 파일 이름과 동일하지 않을 경우)

3. 혹은 같은 이름의 다른 경로의 파일을 연결 시키거나 혼동할 경우에 발생할 수 있는 에러라고 파악했다.

위의 조건만으로는 에러가 해결되지 않아 좀 더 찾아보다가 발견한 점이 있다.

https://ko.myservername.com/what-is-nullpointerexception-java-how-avoid-it

 

Java에서 NullPointerException이란 무엇이며 그것을 피하는 방법 - 다른

이 튜토리얼은 우리가 최소한 예상 할 때 나타날 수있는 Java의 NullPointerException에 대한 모든 것을 설명합니다. 또한이를 피하는 방법에 대해서도 논의 할 것입니다.

ko.myservername.com

위의 블로그에서 도움을 많이 얻었다.

결국 위에 있던 내용도 아니었지만 좋은 공부가 되었다.

결국 java.lang.NullPointerException는 런타임에러인 것인데

문맥적으로는 문제가 없지만 에러가 나는 상황을 의미한다.

여기에서 내가 점검하지 못했던 점까지 생각이 거슬러 올라갔다.

강의의 시점이 2017년이었던 점을 생각을 못했어서 JAVA JDK 버전을 맞추고 진행을 하니 오류가 사라졌다.

오늘은 JAVA에서 런타임 오류가 날 수 있는 경우의 수에 대해서 하나 더 알 수 있었고,

그 오류의 처리 방법에 대해서도 공부해볼 수 있었다.

+ Recent posts