자바 프로그래밍
-
예제 8월 31일 AWT 컴퍼넌트 예제들2009.08.31
-
[Java강의노트] 파일 입출력2009.08.28
-
예제 8월 27일 객체간의 형변환2009.08.27
예제 8월 31일 AWT 컴퍼넌트 예제들
package net.jeongsam.gui; import java.awt.*; class GUIEx01 extends Frame { public GUIEx01() { super("버튼 예제1"); add(new Button("클릭")); setLayout(new FlowLayout()); setSize(300, 100); setVisible(true); } /** * @param args */ public static void main(String[] args) { new GUIEx01(); } }
package net.jeongsam.gui; import java.awt.*; class GUIEx02 extends Frame { public GUIEx02() { super("예제2"); add(new TextArea("안녕하세요.\n자바(JSP)전문가", 5, 15, TextArea.SCROLLBARS_VERTICAL_ONLY)); setLayout(new FlowLayout()); setSize(300, 200); setVisible(true); } /** * @param args */ public static void main(String[] args) { new GUIEx02(); } }
package net.jeongsam.gui; import java.awt.*; class GUIEx03 extends Frame { public GUIEx03() { super("예제2"); add(new Label("로그인:")); add(new TextField("아이디를 입력하세요.", 15)); setLayout(new FlowLayout()); setSize(300, 200); setVisible(true); } /** * @param args */ public static void main(String[] args) { new GUIEx03(); } }
package net.jeongsam.gui; import java.awt.*; class GUIEx04 { Frame fraWin; Panel p1; Panel p2; public GUIEx04() { fraWin = new Frame(); p1 = new Panel(); p1.setLayout(new FlowLayout(FlowLayout.LEFT)); p2 = new Panel(); p2.setLayout(new FlowLayout(FlowLayout.LEFT)); p1.add(new TextField("jeongsy10", 16)); p1.add(new Checkbox()); p1.add(new Label("익명 연결")); p2.add(new TextField("*********", 16)); p2.add(new Checkbox()); p2.add(new Label("비밀번호 저장")); fraWin.setLayout(new GridLayout(10, 1)); fraWin.add(new Label("사이트 이름")); fraWin.add(new TextField()); fraWin.add(new Label("FTP 주소")); fraWin.add(new TextField()); fraWin.add(new Label("사용자 ID")); fraWin.add(p1); fraWin.add(new Label("비밀번호")); fraWin.add(p2); fraWin.add(new Label("리모트 디렉터리(절대경로로 입력)")); fraWin.add(new TextField()); fraWin.setSize(400, 300); fraWin.setVisible(true); } public static void main(String[] args) { new GUIEx04(); } }
package net.jeongsam.gui; import java.awt.*; class GuiEx3 { Frame f; Panel p1; Panel p2; public GuiEx3() { f = new Frame(); p1 = new Panel(); p2 = new Panel(); p1.add(new TextArea("", 12, 30, TextArea.SCROLLBARS_BOTH)); p2.add(new Button("버튼추가")); p2.add(new Button("버튼삭제")); f.add(p1, BorderLayout.CENTER); f.add(p2, BorderLayout.SOUTH); f.setSize(600, 500); f.setVisible(true); } /** * @param args */ public static void main(String[] args) { new GuiEx3(); } }
[Java강의노트] 배열
배열
배열의 선언과 할당
학생들의 점수를 저장한다고 했을 때 각 학생들의 점수를 일일이 변수를 선언하여 저장한다면 여러모로 불편할 것입니다.
class Hackjum1 { public static void main(String[] args) { int cheulYee = 80; int youngHyee = 90; int baDookYee = 100; int sum = cheulYee + youngHyee + baDookYee; System.out.println(sum); } }
만일 학생이 30명이라면 30개의 변수를 선언해야 하고 합계를 구하기 위해 30개의 변수를 나열해야하므로 코드는 악몽이 되어버릴 것입니다. 배열은 이와 같이 같은 타입의 데이터를 모아서 번호를 붙여서 처리하는 방식입니다.
class Hackjum2 { public static void main(String[] args) { int[] hackjum = new int[3]; hackjum[0] = 80; hackjum[1] = 90; hackjum[2] = 100; int sum = 0; for (int i : hackjum) { sum += i; } System.out.println(sum); } }
배열은 다음과 같이 사용합니다.
배열 선언 : 배열을 가리키는 참조 변수를 선언하는 것으로 배열의 타입을 '[]'과 함께 선언한다.
int[] i; int i[]; // 두 표현은 동일한 표현이다.
배열 할당 : 선언된 참조 변수에 배열 인스턴스(객체)를 할당한다. new 연산자를 이용하여 배열 인스턴스를 생성하며 이때 배열의 크기를 지정한다.
i = new int[30];
배열 초기화 : 선언된 배열의 각 요소에 초기값을 할당하는 단계로 배열 참조 변수에 초기값을 할당하는 것으로 배열 할당을 한꺼번에 처리할 수 있다.
i[0] = 0; i[1] = 1; ... i[29] = 29; i = new int[]{0, 1, ..., 29}; i = {0, 1, 2, ..., 29}; // 배열의 초기값을 {}연산자로 할당하여 초기값을 이용하여 배열 인스턴스를 할당할 수 있다.
배열의 각 요소는 인덱스를 통해 접근하며 인덱스는 반드시 0부터 시작한다.
기본형 배열과 참조형 배열
배열은 동일한 타입의 요소들을 하나의 통일된 변수 이름과 인덱스를 이용하여 for 문등과 함께 사용하면 모든 요소를 대상으로 한 작업을 손쉽게 해낼 수 있습니다. 배열의 요소는 기본 데이터 타입뿐만 아니라 객체 타입도 사용할 수 있습니다.
MyClass[] my = new MyClas[30]; // MyClass 타입의 참조 변수를 30개 생성한다. my[0] = new MyClass(); // 배열의 각 요소에 MyClass 인스턴스를 할당한다.
개선된 for 문의 사용
일반적으로 배열의 각 요소로 접근하기 위해서 인덱스를 사용하며 for문을 이용하여 배열의 각 요소를 처리할 수 있습니다.
for (int i = 0; i < array.length; i++) { System.out.println(array[i]); }
자바 5.0부터는 for-each문이라는 새로운 형태의 구문을 제공합니다. 그러나 이 경우 인덱스를 이용한 배열에 대한 직접 접근이 불가능하여 요소의 변경 작업을 할 수 없습니다. 결국 요소의 변경 작업을 위해서는 기존 for문을 사용해야 합니다.
for (int e : array) { System.out.println(e); }
다차원 배열
배열에 저장된 요소가 배열인 경우 다차원 배열이라고 하며 차원의 증가는 로직의 복잡성을 증가시키므로 2차원 이상의 배열 사용은 권장되지 않습니다.
고정 길이 배열
int[][] array; array = new int[2][3]; array[0][0] = 1; array[0][1] = 2; ... array[1][0] = 4; ... array[1][2] = 6; for (int i = 0; i < 2; i++) for (int j = 0; j < 3; j++) System.out.println(array[i][j]);
배열은 총 2 x 3개의 요소를 가지며 2차원 배열로 2개의 인덱스를 사용한다.
가변 길이 배열
int[][] array; array[0] = new int[10]; array[1] = new int[5]; for (int i = 0; i < array.length; i++) for (int j = 0; j < array[i].length; j++) System.out.println(array[i][j]);
배열은 10개의 요소와 5개의 요소를 갖는 가변 길이로 선언된다. 배열의 각 요소에 대한 접근을 위해 i번째 배열의 크기를 저장하고 있는 length 속성을 사용한다.
배열의 조작(java.util.Arrays)
배열의 복사
자바 표준 라이브러리에는 배열의 복사를 위해 System.arrayCopy()라는 static 메서드가 있습니다. 배열을 직접 for문을 이용하여 복사하는 것보다 성능이 뛰어난 메서드입니다. 원본 배열의 요소를 원하는 만큼만 복사본으로 지정된 위치에 복사할 수 있습니다.
class ArrayCopyEx { public static void main(String[] args) { byte[] ar1 = {11, 22, 33, 44, 55}; byte[] ar2 = new byte[10]; System.arraycopy(ar1, 0, ar2, 3, 5); System.out.println("::::: 원본 배열 :::::"); for (byte n : ar1) System.out.println(n); System.out.println("::::: 복사본 배열 :::::"); for (byte n : ar2) System.out.println(n); } }
또한 java.util.Arrays 클래스에서 제공되는 copyOf() 메서드 또한 배열의 복사를 위해 사용할 수 있습니다. System.arrayCoyp()와 달리 원본과 동일 구조로 배열을 복사합니다.
import java.util.Arrays; class ArrayCopyEx2 { public static void main(String[] args) { byte[] ar1 = {11, 22, 33, 44, 55}; byte[] ar2; ar2 = Arrays.copyOf(ar1, 5); System.out.println("::::: 원본 배열 :::::"); System.out.println("배열의 크기 : " + ar1.length); for (byte n : ar1) System.out.println(n); System.out.println("::::: 복사본 배열 :::::"); System.out.println("배열의 크기 : " + ar2.length); for (byte n : ar2) System.out.println(n); } }
배열 비교하기
java.util.Arrays 클래스는 기본형 및 객체형 배열간을 비교하기 위하여 equals() 메서드를 제공합니다. 객체형 배열의 경우 사용자 정의형의 경우 Object.equals() 메서드를 오버라이딩하여야 합니다.
import java.util.Arrays; class ArrayCompEx1 { public static void main(String[] args) { int[] ar1 = new int[10]; int[] ar2 = new int[10]; Arrays.fill(ar1, 10); Arrays.fill(ar2, 10); System.out.println(Arrays.equals(ar1, ar2)); ar1[3] = 15; System.out.println(Arrays.equals(ar1, ar2)); } }
배열 요소의 정렬
Arrays.sort() 메서드는 배열내 요소의 타입을 기반으로 비교를 하여 정렬을 수행합니다. 기본형이 아닌 사용자 정의 타입의 경우 java.lang.Comparable 인터페이스의 compareTo() 메서드를 구현한 클래스를 만들고 Arrays.sort() 메서드를 실행하여 정렬할 수 있습니다.
package net.jeongsam.examples; import java.util.Arrays; class ArraySortEx1 implements Comparable{ int i; public ArraySortEx1() { } public ArraySortEx1(int i) { this.i = i; } /** * comparaTo() 메서드는 동일한 타입의 다른 객체를 인자로 하여 * 현재 객체가 인자 객체보다 작으면 음수 값을 리턴하고 동일하면 0을 크면 1을 리턴한다. */ @Override public int compareTo(ArraySortEx1 obj) { return ((i < obj.i) ? -1 : ((i == obj.i) ? 0 : 1)); } public static void main(String[] args) { ArraySortEx1[] array = {new ArraySortEx1(11), new ArraySortEx1(5), new ArraySortEx1(9), new ArraySortEx1(10), new ArraySortEx1(1)}; System.out.println("정렬전"); for (ArraySortEx1 e : array) System.out.print(e.i + " "); System.out.println(); Arrays.sort(array); System.out.println("정렬후"); for (ArraySortEx1 e : array) System.out.print(e.i + " "); System.out.println(); } }
문자열 배열의 정렬은 사전식 정렬을 하며 콤퍼레이터(Comparator)를 사용하여 대소문자 구분없이 정렬이 가능하도록 할 수 있습니다.
import java.util.Arrays; class ArraySortEx2 { public static void main(String[] args) { String[] array = {"bbc", "Abc", "cBC"}; /* 콤퍼레이터 CASE_INSENSITIVE_ORDER를 사용하여 대소문자 구분하지 않고 정렬 */ Arrays.sort(array, String.CASE_INSENSITIVE_ORDER); for (String s : array) System.out.print(s + " "); System.out.println(); } }
[Java강의노트] 파일 입출력
java.io.File 클래스
디스크에 있는 파일이나 디렉터리의 경로를 관리하는 클래스입니다. File 클래스는 파일이나 디렉터리 경로를 추상화하여 파일의 크기나 디렉터리내의 자식 디렉터리 정보 등을 알 수 있습니다. 그 밖에 파일의 생성과 삭제, 파일의 최종 수정 날짜를 변경하는 등의 기능도 제공합니다.
File 클래스의 생성자와 메서드
생성자 | 설명 |
---|---|
File(File parent, String child) | File 객체 부모 경로명과 문자열인 자식 경로명으로부터 새로운 File 인스턴스를 생성한다. |
File(String pathname) | 지정된 경로 문자열을 이용하여 새로운 File 인스턴스를 생성한다. |
File(String parent, String child) | 부모 경로 문자열과 자식 경로 문자열을 사용하여 File 인스턴스를 생성한다. |
File(URI uri) | 지정된 URI를 사용하여 File 인스턴스를 생성한다. |
리턴 타입 | 메서드 | 설명 |
---|---|---|
boolean | canExecute() | 대상 경로의 파일이 실행 가능한 파일이면 true, 아니면 false 값을 리턴한다. |
boolean | canRead() | 대상 경로의 파일이 읽기 가능한 파일이면 true, 아니면 false 값을 리턴한다. |
boolean | canWrite() | 대상 경로의 파일이 쓰기 가능한 파일이면 true, 아니면 false 값을 리턴한다. |
boolean | createNewFile() | 대상 경로의 빈(empty) 파일을 생성한다. 성공하면 true, 아니면 false 값을 리턴한다. |
boolean | delete() | 대상 경로의 파일 삭제에 성공하면 true, 아니면 false 값을 리턴한다. |
boolean | exists() | 대상 경로의 파일이 존재하면 true, 아니면 false 값을 리턴한다. |
String | getAbsolutePath() | 대상 경로의 절대 경로명을 리턴한다. |
String | getCanonicalPath() | 대상 경로의 정규 경로명을 리턴한다. |
String | getName() | 대상 경로의 파일명이나 디렉터리명을 리턴한다. |
boolean | isDirectory() | 대상 경로가 디렉터리이면 true, 아니면 false 값을 리턴한다. |
boolean | isFile() | 대상 경로가 파일이면 true, 아니면 false 값을 리턴한다. |
String[] | list() | 대상 경로의 모든 파일과 디렉터리를 문자열 배열로 리턴한다. |
boolean | mkdir() | 대상 경로 상의 디렉터리를 만들면 true, 아니면 false 값을 리턴한다. |
boolean | renameTo(File dest) | 지정된 파일명으로 변경한다. |
long | lastModified() | 지정된 파일의 최종 변경 시간을 밀리초로 리턴한다. |
long | length() | 지정된 파일의 크기를 리턴한다. |
File 클래스를 사용한 예
package net.jeonsam.examples; import java.io.*; class FileInfo { /** * @param args */ public static void main(String[] args) throws IOException { String filePath = "C:\\"; File f1 = new File(filePath); String list[] = f1.list(); for (int i = 0; i < list.length; i++) { File f2 = new File(filePath, list[i]); if (f2.isDirectory()) { System.out.println(list[i] + " : 디렉터리"); } else { System.out.println(list[i] + " : 파일(" + f2.length() + ")bytes"); } } File f3 = new File("C:\\test.txt"); System.out.println(f3.createNewFile()); System.out.println(f3.getAbsolutePath()); System.out.println(f3.getCanonicalPath()); System.out.println(f3.getPath()); System.out.println(f3.getName()); System.out.println(f3.getParent()); File f4 = new File("C:\\test.txt"); File f5 = new File("C:\\test1.txt"); System.out.println(f4.renameTo(f5)); } }
File 객체로 할 수 있는 작업들
① 기존 파일을 나타내는 File 인스턴스를 생성한다.
File f = new File("MyFile.txt");
② 새로운 디렉터리를 생성한다.
File dir = new File("MyDirectory"); dir.mkdir();
③ 디렉터리의 내용을 출력한다.
if (dir.isDirectory()) { String[] dirContents = dir.list(); for (int i = 0; i < dirContents.length; i++) { System.out.println(dirContents[i]); } }
④ 파일이나 디렉터리의 절대 경로명을 출력한다.
System.out.println(dir.getAbsolutePath());
⑤ 파일이나 디렉터리를 삭제한다.
boolean isDeleted = f.delete();
텍스트 파일 읽기
BufferedReader reader = new BufferedReader(new FileReader(new File());
버퍼를 이용하여 텍스트 파일의 내용을 한 행씩 읽어들이는 예입니다. BufferedReader만 close 시키면 다른 스트림도 자동으로 close 됩니다.
package net.jeonsam.examples; import java.io.*; class ReadTextFile { /** * @param args */ public static void main(String[] args) { try { File myFile = new File("C:\\MyText.txt"); FileReader fileReader = new FileReader(myFile); BufferedReader reader = new BufferedReader(fileReader); String line = null; while ((line = reader.readLine()) != null) { System.out.println(line); } reader.close(); } catch (Exception ex) { ex.printStackTrace(); } } }
split()을 이용하여 파싱하기
String str = "Thinking in Java/중급서" String[] res = str.split("/"); for (String t : res) { System.out.println(t); }
텍스트 파일 쓰기
BufferedWriter writer = new BufferedWriter(new FileWriter(new File());
연습문제.
이름/전화번호 형식으로 저장된 텍스트 파일을 읽어서 이름에 해당하는 전화번호 찾기
예제 8월 28일 강사, 수강생 및 남, 녀 성비 계산 (다형성과 instanceof 연산의 활용)
package net.jeongsam.petshop; import java.util.ArrayList; import java.util.Random; class CountTest { /** * @param args */ public static void main(String[] args) { int maleTeachers = 0; int femaleTeachers = 0; int maleStudents = 0; int femaleStudents = 0; Student s = null; Teacher t = null; ArrayListpersons = new ArrayList (); for (int i = 0; i < 500; i++) { switch (new Random().nextInt(5)) { case 0: case 1: case 2: case 3: s = new Student(); s.setGender((new Random().nextInt(2) == 0) ? 'M' : 'F'); persons.add(s); break; default: t = new Teacher(); t.setGender((new Random().nextInt(2) == 0) ? 'M' : 'F'); persons.add(t); break; } } for (Person p : persons) { if (p instanceof Teacher && p.getGender() == 'M') { maleTeachers++; } else if (p instanceof Teacher && p.getGender() == 'F') { femaleTeachers++; } else if (p instanceof Student && p.getGender() == 'M') { maleStudents++; } else { femaleStudents++; } } System.out.println("남자 강사의 수 : " + maleTeachers + "명"); System.out.println("여자 강사의 수 : " + femaleTeachers + "명"); System.out.println("남자 수강생의 수 : " + maleStudents + "명"); System.out.println("여자 수강생의 수 : " + femaleStudents + "명"); } }
예제 8월 27일 객체간의 형변환
기본 데이터 타입(primitive type)간의 형변환은 큰 타입이 작은 타입을 포함하는 개념인 반면, 객체 참조 변수(reference type)간의 형변환은 부모클래스와 자식 클래스간의 상속 관계가 전제가 되었을 경우 자식클래스를 객체로 생성하면, 자식 클래스 타입의 참조변수를 부모 클래스 타입으로 형변환이 가능하며, 그 반대도 가능해진다.
package net.jeonsam.examples; public class Animal { public String name; public String toString() { return name; } }
package net.jeonsam.examples; public class Duck extends Animal { public String name; public void fly() { System.out.println("파닥파닥!!"); } }
package net.jeonsam.examples; public class Dog extends Animal { public String name; public void bark() { System.out.println("멍멍!!"); } }
package net.jeonsam.examples; public class InheriTest { /** * @param args */ public static void main(String[] args) { Dog2 dog = new Dog2(); Animal2 duck = new Duck(); Animal2 animal = new Animal2(); dog.name = "바둑이"; duck.name = "도날드 덕"; animal.name = "짐승!"; System.out.println(dog.name); System.out.println(duck.name); // 자식클래스를 부모클래스로 형변환 가능 System.out.println(((Animal2)dog).name); // 원래 자식클래스로 되돌림 System.out.println(((Duck)duck).name); // 부모클래스를 자식클래스로 형변환 System.out.println(((Duck)animal).name); // Runtime Exception 클래스간 형변환 오류!! } }