본문 바로가기

programming/Gukbi

국비 교육 23일차 - 라이브러리 활용

728x90
반응형

아마 내일까지는 계속 라이브러리 활용일것 같다

그중에서도 오늘은 String이랑 Math, Calendar 조금을 배우고.. 내일부터 자바의 정석 2권 진도를 나가지 않을까 싶다. 

 

이쯤되니 진도가 빠른게 아니라 그냥 날라다닌다

내가 뭘 이해한건지 뇌에 입력되긴 한건지 의문이다... 그래서 복습하고 있는거긴 하지만...

 

 

package com.sist.movie;
import java.io.*;
// String/StringBuffer
public class MovieManager {
   // 모든 사용자(user)가 같은 영화정보를 공유한다 
   private static MovieVO[] movie=new MovieVO[1938]; // 싱글턴 
   // 1. 파일에서 데이터를 읽어서 배열에 저장 => 초기화 
   /*
    *   1. 명시적 초기화 
    *   2. 생성자 : 사용자의 입력값을 받아서 초기 : 오버로딩 
    *   3. 초기화 블럭 : 사용자의 입력값을 받아서 초기화 (X) => 인스턴스블럭보다 static블럭일 경우에 주로 사용 
    *   
    */
   static
   {
	   // 파일에서 읽어서 저장을 할 수 있다 => 구현 
	   // 파일 전체 읽기
	   // 읽은 데이터 => 분리 => MovieVO에 저장
	   try
	   {
		   StringBuffer sb=new StringBuffer();
		   int i=0;
		   FileReader fr=new FileReader("c:\\javaDev\\movie.txt"); // IO(CheckException)
		   while((i=fr.read())!=-1)
		   {
			   sb.append(String.valueOf((char)i));//문자를 한글짜 읽어서 메모리에 저장한다 
			   // valueOf() : web,윈도우,네트워크 => 문자열만 사용(String)
		   }
		   fr.close();
		   // 배열에 저장 
		   String data=sb.toString();
		   String[] movie_data=data.split("\n");
		   i=0;// 배열 첨자(배열 인덱스)
		   // String m==> 1938
		   for(String m:movie_data)
		   {
			   //System.out.println(m);
			   String[] vo=m.split("\\|"); // split는 정규식 => 사용중인 
			   movie[i]=new MovieVO();// 1938개 생성 
			   // MovieVO[] movie=new MovieVO[1938]; => 메모리가 생성 
			   // MovieVO[] movie={null,null,......}
			   // int[] arr=new int[10]; => 0,0,0
			   // arr[0]=10;
			   movie[i].setMno(Integer.parseInt(vo[0])); 
			   // 문자열을 정수로 변환 Integer.parseInt(문자열)
			   movie[i].setTitle(vo[1]);
			   movie[i].setGenre(vo[2]);
			   movie[i].setPoster(vo[3]);
			   movie[i].setActor(vo[4]);
			   movie[i].setRegdate(vo[5]);
			   movie[i].setGrade(vo[6]);
			   movie[i].setDirector(vo[7]);
			   
			   /*
			    *    ^ : 부정 , 시작    [^A-Z]:알파벳 대문자 제외 , ^[A-Z] : 대문자로 시작
			    *    $ : 끝 [0-9] : 숫자로 끝난 문자열
			    *    + : 한글자 이상이 존재 
			    *        맛있+ => 맛있는 , 맛있고 ...
			    *    * : 0이상 
			    *    | : 선택   => 맛있|맛없
			    *    ? : 앞에,뒤에 한글자 포함 
			    *    . : 임의의 한글 
			    *    ===> 일반 문자열로 사용 => \\
			    */
			   i++;
		   }
	   }catch(Exception ex){}
   }
   
   /*
    *    class A
    *    {
    *        선언만 가능 (예외처리,제어문,연산처리 , 값대입 (X))
    *        int a=10; (O)
    *        int a;
    *        a=10; (X)
    *    }
    */
   // 기능 설계 (메소드)
   // 첫번째 => 목록 출력 
   public static MovieVO[] movieListData(int page)
   {
	   // 페이지 나누기 
	   MovieVO[] m=new MovieVO[10];
	   if(page==movieTotalPage())
	   {
		   m=new MovieVO[movie.length%10];
	   }
	   int j=0;
	   int rowSize=10;
	   int pagecnt=(rowSize*page)-rowSize; // 페이지의 시작점
	   /*
	    * 	1page => 0~9
	    * 	2page => 10~19
	    * 	
	    */
	   for(int i=0; i<movie.length; i++)
	   {
		   if(j<10 && i>=pagecnt)
		   {
			   m[j]=movie[i];
			   j++;
		   }
	   }
	   
	   return m;
   }
   // 두번째 => 총페이지 
   public static int movieTotalPage()
   {
	   int count=movie.length;
	   int total=(int)(Math.ceil(count/10.0)); // 1938/10.0  => 193.8(0이상=> 올림) => 194
	   return total;
   }
   
   
   // 영화 상세보기 => MovieVO (영화 1개에 대한 모든 정보) => ArrayList,Vector(컬렉션)
   public static MovieVO movieDetailData(int mno)
   {
	   MovieVO vo=new MovieVO();
	   // vo에 값을 채운다
	   vo=movie[mno-1]; // 영화번호는 1번부터 시작, 배열의 인덱스는 0번부터 시작
	   return vo;
   }
   /* 	배열이 넘어올수도 있고, 직접 만든 데이터형이 넘어올 수도 있음
    * 	1. 목록 => 영화 정보 여러개 => 한개로 묶어서 전송
    * 							 ============ MovieVO[] 
    * 	2. 영화 한개의 상세보기 => MovieVO
    * 	3. 영화명만 출력 (여러개: String[], 한개: String)
    * 	
    * 	클래스 : 여러개의 다른 데이터를 묶어서 관리하는 데이터형
    * 		   =============== 사람 : 한명에 대한 모든 정보, 영화 : 영화 한개에 정보
    */
   // 출연자로 => 영화 제목 출력 : contains
   //public static String[] 
   public static String[] movieFindData(String actor)
   {
	   // 배열을 선언 하기 위한 총 갯수를 확인
	   // 배열의 단점은 고정 데이터 (가변이 아니다) : 컬렉션 - 
	   int count=0;
	   for(MovieVO vo: movie)
	   {
		   if(vo.getActor().contains(actor))
		   {
			   count++;
		   }
	   }
	   
	   String[] movie_title=new String[count];
	   int i=0;
	   for(MovieVO vo:movie)
	   {
		   if(vo.getActor().contains(actor))
		   {
			   movie_title[i]=vo.getTitle();
			   i++;
		   }
	   }
	   return movie_title;
   }
   
   // 영화명 => 영화 찾기 : contains
   public static String[] findTitleData(String title)
   {
	   int count=0;
	   for(MovieVO vo:movie)
	   {
		   if(vo.getTitle().startsWith(title))
		   {
			   count++;
		   }
	   }
	   String[] movie_title=new String[count];
	   int i=0;
	   for(MovieVO vo:movie)
	   {
		   if(vo.getTitle().startsWith(title))
		   {
			   movie_title[i]=vo.getTitle();
			   i++;
		   }
	   }
	   return movie_title;
   }
   
   // 시작하는 영화명 찾기 : startsWith, endsWith
   
}

굉장히 길었다. 이 프로그램의 핵심은 String 라이브러리들을 통해서 영화 정보를 출력, 찾아오기 등을 하는것이었다. 먼저 StringBuffer를 이용해서 파일의 내용을 긁어왔다. 긁어온 내용을 읽어서 메모리에 저장하고, 그 저장한 데이터들을 처리해서 필요한 데이터들을 가지고 오는 형식으로 프로그램이 이루어졌다. 

 

split을 사용해서 영화 번호, 제목, 장르, 포스터, 배우, 개봉일, 등급, 감독을 나눠주고

문자 배열에 저장을 해줬다. 

파일을 읽어오는 과정에서 에러가 발생할 수 있기 때문에 try~catch를 사용해서 발생할 수 있는 에러를 미리 잡아줬다.

 

영화가 총 1900개가 넘었기 때문에 10개씩 페이지를 나누어 출력하기 위한 코드를 짜야했다.

사용자가 page의 숫자를 입력하면 그 해당하는 페이지의 가장 첫번째 목록부터 마지막 목록까지 총 10개를 출력하는 코드를 짜줬다. 

 

그리고 movieTotalPage함수에서는 Math.ceil 함수를 사용해서 최종 페이지를 출력해주는 코드를 완성해줬다. 

 

movieDetailData함수를 통해서 사용자가 선택한 영화의 정보들을 다시 vo에 담아준다. -> main에서 get함수를 통해서 해당하는 정보들을 출력해 줬다. 

 

movieFindData는 사용자가 배우 이름을 입력하면, 배우가 출연한 모든 영화들의 정보를 가지고 온다. 

배열의 크기가 어떻게 될지 모르니 일단 count 변수를 통해 있는 만큼 세준 다음에, 그 정보를 활용해서 배열을 만들어 준다. 

 

그리고 forEach 구문을 돌려서 배우가 출연한 영화들의 제목을  getTitle을 통해 꺼내온다. 

 

마찬가지 비슷한 구조로 startsWith를 통해 문자열로 시작하는 영화명을 찾는 함수를 만들어준다. 

 

여기까지가 위 코드의 내용이었다. 

 

 

package com.sist.movie;
import java.util.Scanner;
public class UserMain {

	public static void main(String[] args) {
		Scanner scan=new Scanner(System.in);
		// 영화정보를 볼 페이지를 입력하시오
		int totalpage=MovieManager.movieTotalPage();
		
		
		int page=1; 
		// 페이지가 정상으로 입력되었는지 오류체크
		while(true)
		{
			System.out.print("영화 목록을 볼 페이지 지정 (1~"+totalpage+"):");
			String s=scan.next();
			page=Integer.parseInt(s); // 문자열을 정수형으로 변경 => 문자열 변경 => String.valueOf()
			if(page<1 || page>totalpage)
			{
				System.out.println("존재하지 않는 페이지 입니다!!");
				continue;
			}
			break;
		}
		System.out.println("======현재 보고 있는 페이지는 "+page+"page 입니다======");
		MovieVO[] movie=MovieManager.movieListData(page);
		for(MovieVO vo: movie)
		{
			System.out.println("영화번호:"+vo.getMno());
			System.out.println("영화명:"+vo.getTitle());
//			System.out.println("장르:"+vo.getGenre());
//			System.out.println("감독:"+vo.getDirector());
//			System.out.println("출연:"+vo.getActor());
//			System.out.println("등급:"+vo.getGrade());
//			System.out.println("개봉일:"+vo.getRegdate());
			System.out.println("================================");
		}
		
		System.out.print("영화 datail 확인할 영화번호를 입력하세요");
		int detail_no=scan.nextInt();
		MovieVO vo=MovieManager.movieDetailData(detail_no);
		System.out.println("=========="+vo.getTitle()+" 상세보기===========");
		System.out.println("장르:"+vo.getGenre());
		System.out.println("감독:"+vo.getDirector());
		System.out.println("출연:"+vo.getActor());
		System.out.println("등급:"+vo.getGrade());
		System.out.println("개봉일:"+vo.getRegdate());
		System.out.println("================================");
		System.out.print("출연자 이름을 입력:");
		String name=scan.next();
		String[] title=MovieManager.movieFindData(name.trim());
		for(String s:title)
		{
			System.out.println(s);
		}
		System.out.println("================================");
		System.out.println("영화명 입력:");
		String str=scan.next();
		title=MovieManager.findTitleData(str.trim());
		for(String t:title)
		{
			System.out.println(t);
			try
			{
				Thread.sleep(100); // Check Exception => 잠시멈춤
			}catch(Exception e) {}
		}
		
	}

}

여기까지 인데 솔직히 보면서도 그렇게 잘 이해가 가진 않는다. 특히나 정처기 접수한다고 거의 설명을 못들었었다.

왜 하필이면 오늘이어야 했을까

 

짜증난다

 

나중에 또 나올것 같으니 그때 다시 이해해보도록 하겠다..

 

 

다음은 Math 활용에 대해서 배웠는데, 활용되는 범위가 한정적이서 비교적 쉽게 짚고 넘어갈 수 있었다. 

 

package com.sist.math;
// Math
/*
 * 	ceil() : 올림 메소드 ==> public static double ceil(double d)
 * 	int count=38;
 * 	int total=count/10; => total=3
 * 	if(total%10>0)
 * 		total++; total=4
 * 	
 * 	int count=38;
 * 	int total=(int)(Math.ceil(count/10.0)) total=4
 * 
 * 	==> SELECT CEIL(COUNT(*)/10.0) FROM movie => SQL(검색)
 * 
 * 	random() => 컴퓨터에서 임의의 수를 가지고 온다 (난수) ==> public static double random()
 * 	========
 * 		0.0~0.99 사이의 실수륿 발생
 * 
 */
public class MainClass {

	public static void main(String[] args) {
		//ceil
		int count=47;
		int total=(int)(Math.ceil(count/10)); // total=4
		System.out.println(total);
		
		// random()
		int data=(int)(Math.random());
		System.out.println(data);
	}
}

올림 method Ceil과 random() 메소드 정도만 알아도 Math는 무난하게 넘어가도 되는듯 싶었다. 

 

package com.sist.math;
/*
 * 	Wrapper : 기본데이터형을 클래스화 시킨 클래스들의 집합
 * 	======= 
 * 	정수형
 * 	 byte 	============= Byte
 * 	 short	============= Short
 * 	 int 	============= Integer ****  변환) 문자열 => 정수 : parseInt("문자열")
 * 											=> 에러 (정수변환이 안될때 NumberFormatException)
 * 											=> http://localhost/board/list.jsp?page=1 (전송)
 * 												String page=request.getParameter("page");
 * 											  	int page=Integer.parseInt(page);
 *   long 	============= Long ****	=> Long.parseLong("문자열")
 * 	실수형
 *   float	============= Float
 *   double ============= Double **** => Double.parseDouble("10.5")
 * 	문자형
 *   char 	============= Character
 * 	논리형
 *   boolean ============ Boolean **** => Boolean.parseBoolean("true") 
 * 	
 * 	==> 데이터형처럼 사용이 가능
 * 	Integer i=10;
 * 	int j=i;
 * 
 */
import java.util.Scanner;

public class MainClass2 {

	public static void main(String[] args) {
		/*Scanner scan=new Scanner(System.in);
		System.out.print("첫번째 숫자 입력:");
		String s1=scan.next();
		int i=Integer.parseInt(s1.trim()); // 공백문자 제거후 정수형으로 변환
		System.out.print("두번째 숫자 입력:");
		String s2=scan.next();
		int j=Integer.parseInt(s2);
		
		// 연산자
		System.out.println(s1+s2);
		System.out.println(i+j);*/
		int i=100;
		Integer ii=i; //오토박싱
		int j=ii; //언박싱
		// 일반 데이터형과 클래스형이 호환되어 처리 될 수 있다. 
		Boolean boo=true;
		boolean b=boo;
		Long l=10L;
		long l2=l;
		Double d=10.5;
		double d2=d;
		
		String ss="true";
		boolean bb=Boolean.parseBoolean(ss); //true
		
		String ss1="10.5";
		double dd=Double.parseDouble(ss1);
		
		String ss2="1000000000000000000";
		long ll =Long.parseLong(ss2);
		
		System.out.println(ss);
		System.out.println(dd);
		System.out.println(ll);
		
		int k1=Integer.parseInt("100",2); //100, 2진법으로 표현
		int k2=Integer.parseInt("1000"); // 1000 (10진법 표현)
		int k3=Integer.parseInt("100",8); // 100 8진법으로 표현
		System.out.println(k1);//4-2진법으로 변환한것
		System.out.println(k2);
		System.out.println(k3);
		/*
		 * 	자바에서 숫자 표현
		 * 	2진법
		 * 	8진법
		 * 	16진법
		 *  10진법
		 *  
		 */
		int k5=789;
		System.out.println(Integer.toBinaryString(k5)); //2진법
		System.out.println(Integer.toHexString(k5)); //16진법
		System.out.println(Integer.toOctalString(k5)); //8진법
		
		Integer k6=10;
		String sss=k6.toString(); // 문자열로 변환 되었음
		Integer k7=20;
		
		System.out.println(k6+k7);
		long lll=10; // 자동으로 long형으로 변환됨
		Long k8=lll; // Long클래스안에는 반드시 long만 사용할 수 있다. 
		
		
		
	}

}

Wrapper 클래스 - 기본 데이터형들을 클래스와 시킨 클래스들의 집합. 대표적인 예시로 parse가 있었다. 

parseInt() 등을 통해 특정 데이터들을 정수, 실수 등으로 변환해줄 수 있었다. 

 

다음은 java.lang의 클래스들

 

package com.sist.util;
/*
 *    java.lang.*
 *    ============
 *      Object , String , StringBuffer , Wrapper , Math
 *      => final 클래스(상속을 받아서 오버라이딩이 불가능)
 *    java.util.*
 *      = 문자열 분리 : StringTokenizer (split 대체)
 *      = 날짜 관리 : Date , Calendar
 *      = 난수 관리 : Random  => nextInt(10)
 *      = 자료 구조 : Collection
 *                  ========== List,Set,Map(interface) => 웹 핵심 
 *    java.sql.* : 오라클 연동 
 *      = Connection : 연결 
 *      = Statement : SQL문장 전송 
 *      = ResultSet : 결과값을 읽어 온다 
 *    java.io.*
 *    java.net.*
 *      = URL 
 *      = URLEncoder
 *    ==================================================
 *    웹 : javax~ (Servlet => JSP => Struts => Spring)
 *                ========   ====             ======= Maven
 *        Request , Response , Session , Cookie => Newwork
 */
import java.util.*; // * 은 모든 클래스 
public class MainClass {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Random r=new Random();// 일반 클래스 
        //int data=r.nextInt(10); // int범위 (0~9)
        // 0~99 +1 1~100
        //System.out.println(data);
        int[] arr=new int[100];
        for(int i=0;i<100;i++)
        {
        	arr[i]=r.nextInt(10);
        }
        
        // 출력 
        for(int i=0;i<100;i++)
        {
        	if(i%10==0 && i!=0)
        	{
        		System.out.println();
        	}
        	System.out.print(arr[i]);
        }
	}

}

일반 클래스를 활용해서 써준 코드이다. 

 

아래는 Calendar 클래스를 사용하지 않고 날짜를 입력하면 그 날짜의 요일을 출력하는 코드

package com.sist.main;
import java.util.*;
class Diary
{
	public void myDate()
	{
		Scanner scan=new Scanner(System.in);
		System.out.print("년도 입력:");
		int year=scan.nextInt();
		System.out.print("월 입력:");
		int month=scan.nextInt();
		System.out.print("일 입력:");
		int day=scan.nextInt();
		
		// 전년도
		int total=(year-1)*365
				+(year-1)/4
				-(year-1)/100
				+(year-1)/400;
		int[] lastDay= {31, 28, 31, 40, 31, 30,
						31,31,30,31,30,31};
		if((year%4==0 &&year%100!=0)||(year%400==0))
			lastDay[1]=29;
		else 
			lastDay[1]=28;
		
		// 전달
		for(int i=0; i<month-1; i++)
		{
			total+=lastDay[i];
		}
		
		// +day
		total+=day;
		// %7
		int week=total%7;
		String[] strWeek= {"일", "월", "화", "수", "목", "금", "토"};
		System.out.printf("%d년도 %d월 %d일은 %s요일 입니다.\n", year, month, day, strWeek[week]);
		
	}
}
public class MainClass {

	public static void main(String[] args) {
		
			Diary d=new Diary();
			d.myDate();
	}

}

윤년계산을 직접 해줘야 한다는 단점이 있다.

 

package com.sist.main;
import java.util.*;
import java.text.*;
//class A
//{
//	private static A a=null;
//	public static A getInstance()
//	{
//		if(a==null)
//			a=new A();
//		return a;
//	}
//}
/*
 * 	year/day 상관 x
 * 	month => 0~11 ==> 저장할 때는 반드시 month-1
 * 	week => DAY_OF_WEEK ==> 1~7 
 */
public class MainClass2 {

	public static void main(String[] args) {
		Calendar cal=Calendar.getInstance(); // 싱글턴 (static)
		
		/*Scanner scan=new Scanner(System.in);
		System.out.print("년도 입력:");
		int year=scan.nextInt();
		System.out.print("월 입력:");
		int month=scan.nextInt();
		System.out.print("일 입력:");
		int day=scan.nextInt(); 
		
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month-1);
		cal.set(Calendar.DATE, day);
		
		year=cal.get(Calendar.YEAR);
		month=cal.get(Calendar.MONTH); // 0~11
		day=cal.get(Calendar.DATE);
		
		int week=cal.get(Calendar.DAY_OF_WEEK)-1; // 1~7
		String[] strWeek = {"일", "월", "화", "수", "목", "금", "토"};
		
		String msg=String.format("%d년도 %d월 %d일 %s요일입니다", cal.get(Calendar.YEAR), 
				cal.get(Calendar.MONTH)+1, cal.get(Calendar.DATE), strWeek[week]);
		System.out.println(msg);*/
		Date date =new Date(); // 시스템의 날짜(시간) ==> 오라클 저장시에 사용
		System.out.println(date);
		SimpleDateFormat sdf=new SimpleDateFormat("2005-MM-dd hh:mm:ss");
		System.out.println(sdf.format(date));

	}

}

이렇게 Calendar 클래스를 활용하면 굳이 윤년 계산을 해줄 필요없이 달력을 사용할 수 있다. 

 

 

여기까지 복습끝....

 

 

 

 

728x90
반응형