[Java] 자바 정리2 - 중요 클래스, 메소드, 컬렉션, IO
10. 중요 메소드
① toString() : 오버라이딩을 통한 사용자 정의 toString()
public String toString(){
String 변수 = 출력하고 싶은 문자열+...
return 변수;
}
Object obj1= new Object(); // 최상위 객체
System.out.println(obj1.getClass()); // 클래스 이름
System.out.println(obj1.hashCode()); // 객체가 갖는 고유한 값 - 주소(10진수)
System.out.println(obj1.toString()); // 클래스 이름 @ 16진수의 hash code
// java.lang.Object@123a439b
System.out.println(obj1); // toString()과 동일
String s = new String("str"); // String과 Date는 toString()이 오버라이딩된 값이 출력됨
Date d = new Date();
System.out.println(s); // s.toString이 호출.(toString() 기본 메소드로 생략됨)
System.out.println(d); // d.toString이 호출.(toString() 기본 메소드로 생략됨)
Random r = new Random(); // 그외 Random, 사용자 정의함수는 주소값을 리턴한다.
Person p = new Person();
System.out.println(r);
System.out.println(p);
② equals() : 오버라이딩을 통한 사용자 정의 equals().
사용자 정의 객체의 경우 주소값을 비교함으로 equals 비교시 false를 리턴
class Person{
...
public boolean equals(Object obj) { // Person객체끼리 비교
if(obj != null & obj instanceof Person) {
// obj가 Person이라고 하더라도 타입이 Object이므로 Object의 멤버만 사용할 수 있으므로
// obj를 Person으로 캐스팅하여 Person.equals를 사용한다.
Person p = (Person) obj;
if(this.name.equals(p.getName()) & this.addr.equals(p.getAddr())) {
return true;
}
}
return false;
}
}
Person obj1 = new Person();
Person obj2 = new Person();
if(obj1.equals(obj2)){ // 사용자 정의된 equals() 비교
}
11. 중요 클래스
① String : 문자열 생성은 2가지 방법 존재.
1) String 생성
String str = new String("문자열"); // new 이용
String str = "문자열"; // 리터럴 이용
- new를 이용 시 동일한 문자열이 존재하여도 새로 생성.
- 리터럴을 이용 시 동일한 문자열이 존재할 경우 기존 문자열 재사용. 상수풀(constant pool)에 저장되어 불변성
을 가짐.
- String 객체의 문자열이 어떤 방법으로 할당되는지 상관없이 문자열을 비교하고 싶은 경우 equals()사용
2) String 생성자
byte[] data = {65,66,67,69,70};
char[] data2 = new char[] {'0','1','0','-','1','2','3'};
String str1 = new String(data); // ABCEF
String str2 = new String(data2); // 010-123
String str3 = new String(data2,2,2); // data2의 2번 index 부터 2개의 문자열. "1-"
- String클래스를 사용하는 경우 다양한 타입의 입력데이터를 문장열로 만들 수 있도록 하기 위해
다양한 형태의 생성자가 오버로딩 되어있음.
3) String - final
class MyClass extends String{
}
- String은 final class로 상속할 수 없음.
4) String 메소드 : String 객체는 원본이 변경되지않고 메소드 실행결과로 새로운 String객체가 만들어짐.
: 문자열 조작이 많은 곳에서 String을 사용하는 것은 프로그램을 무겁게 함.
String str1 = new String("java programming");
String str2 = new String("입니다.");
str1.charAt(1); // str1에서 1번 index의 문자
str1.concat(str2); // str1과 str2를 연결
str1.indexOf('a'); // str1에서 가장 왼쪽의 'a'의 index
str1.indexOf("합"); // 문자가 없을 경우 -1 리턴
str1.lastIndexOf('a'); // str1에서 가장 오른쪽의 'a'의 index
str1.length(); // str1의 길이
str1.equalsIgnoreCase("java programming");
str1.equalsIgnoreCase("JAVA programming"); // 대소문자 구분하지않고 문자열 비교
str1.startsWith("java")); // str1이 "java"로 시작하면 true아니면 false 리턴
str1.endsWith("amming")); // str1이 "amming"로 끝나면 true아니면 false 리턴
str1.toUpperCase(); // 대문자 변환값 리턴
// 원본 문자열 변화 없음. 새로운 객체를 생성하여 리턴.
str1.toLowerCase()); // 소문자 변환값 리턴
str1.substring(4); // 4번째 문자열부터 끝까지의 문자열 추출. programming
str1.substring(4,8); // 4번째 문자열부터 8-1번까지의 문자열 추출. pro
str1.replace('a','A')); // 'a' 문자를 'A'로 변경. jAvA progrAmming
5) String 의 데이터 타입 변환과 관련된 메소드
String str1 = new String("java programming");
String str2 = new String("java servlet spring bigdata");
//1) getBytes() : String -> byte[] 변환
byte[] data1 = str1.getBytes();
for(int i=0;i<data1.length;i++) {
System.out.print(data1[i]+" ");
}
//2) toCharArray() : String -> char[] 변환
char[] data2 = str1.toCharArray();
for(int i=0;i<data2.length;i++) {
System.out.print(data2[i]+" ");
}
//3) split(" ") : String -> String[] 변환
String[] data3 = str2.split(" ");
for(int i=0;i<data3.length;i++) {
System.out.print(data3[i]+" ");
}
//4) valueOf(x) : 기본형 -> String 변환
int i =1000;
double d = 10.5;
test(String.valueOf(i));
test(String.valueOf(d));
test(i+"");
test(d+"");
public static void test(String data) {
System.out.println("변환된 데이터 "+data);
}
6) StringBuffer : String의 불변성으로 메모리 사용이 많아 대안으로 원본 배열이 변경되는
StringBuffer사용하기도 함.
① StringBuffer와 StringBuilder의 차이
StringBuffer : thread 고려 무겁다 안전. JDK 1.0이상
StringBuilder : thread 비고려 가볍다 웹서버에서 처리함으로 무관. JDK 5.0이상
② StringBuffer 사용
StringBuffer sb = new StringBuffer("java programming");
sb.append("입니다."); // 맨뒤에 추가
sb.insert(2, "자바"); // 지정한 위치에 문자열 삽입
sb.delete(2, 6); //start~end-1 위치의 문자열 삭제
sb.reverse(); // 문자열 반전
③ String과 StringBuffer의 비교
public static void stringCheck(int count) {
// 시작할때 현재 시간을 측정 - nano초
long start = System.nanoTime();
String str = new String("java");
for(int i=1; i<=count;i++) {
str+="java";
}
long end = System.nanoTime();
System.out.print("str+='java' ");
System.out.println("수행시간\t: "+(end-start)+" ns");
}
public static void stringBufferCheck(int count) {
long start = System.nanoTime();
StringBuffer sb = new StringBuffer("java");
for(int i=1; i<=count;i++) {
sb.append("java");
}
long end = System.nanoTime();
System.out.print("sb.append('java') ");
System.out.println("수행시간\t: "+(end-start)+" ns");
}
public static void main(String[] args) {
int count = 10000;
System.out.println("실행횟수 : "+count);
stringCheck(count);
stringBufferCheck(count);
}
② Math
Math.PI; // PI
Math.abs(-1); // 절대값
Math.ceil(10.5); // 올림
Math.round(10.5); // 반올림
Math.floor(10.5); // 버림
Math.max(100,10); // 최대값
Math.min(100,10); // 최소값
Math.random(); // 난수
③ Wrapper 클래스
1) 5.0 이전(기본형 -> 참조형)
int num =100;
Integer obj = new Integer(num); // 기본형 -> 참조형
run(obj);
public static void run(Object obj) { // Integer -> Object
Integer inObj = (Integer)obj; // Object -> Integer
int num = inObj.intValue(); // Interger -> int (참조형->기본형)
}
2) 5.0 이후 (기본형 -> 참조형)
int num = 1000; // 5.0 이후 버전의 jdk에서는 컴파일러가 자동으로 변환해준다.
run(num); // 참조형으로 매개변수가 정의되어 있어도 기본형을 전달하는 경우 자동으로
// 컴파일러가 Integer in = new Integer(num) 이 코드를 실행해서
// Integer타입으로 변환해준다. 이를 오토박싱이라 한다.
public static void run(Object obj) {
Integer inObj = (Integer)obj;
int i = inObj; // (참조형->기본형)
int j = (Integer)obj; // 오토 언박싱
// int형 변수에 참조형 변수를 전달하는 경우 컴파일러가 자동으로 객체를
// int로 바꾸는 코드를 만든다.
// int j = obj.intValue();
}
④ Calendar 클래스 : 날짜 시간
//java.util.date : 시스템의 기본 날짜와 시간
//java.sql.date : DBMS(오라클)에서 date타입으로 전의한 칼럼값을 다루기 위해서 사용하는 타입
//Date 객체는 deplecate
//GregorianCalendar는 Calendar의 자식 클래스
import java.util.Calendar;
Calendar cal = new GregorianCalendar(); // 오늘 날짜기간 정보
cal.get(Calendar.YEAR);
cal.get(Calendar.MONTH)+1;
cal.get(Calendar.DATE);
cal.get(Calendar.HOUR);
cal.get(Calendar.MINUTE);
cal.get(Calendar.SECOND);
cal.getTimeInMillis();
cal.set(2020,11,30);
⑤ SimpleDateFormat 클래스 : 출력되는 데이터의 형식을 변경할 수 있는 API
SimpleDateFormat sdf = new SimpleDateFormat("yyyy년MM월dd일");
Calendar today = new GregorianCalendar();
sdf.format(today.getTime()); //getTime() : Calendar객체를 Date로 변환
⑥ DecimalFormat 클래스 : 출력되는 데이터의 형식을 변경할 수 있는 API
import java.text.DecimalFormat;
DecimalFormat df = new DecimalFormat("#,###.##");
df.format(1234567);
df.format(1234567.48);
String data = "25465.174";
df.format(Double.parseDouble(data);
try {
double data3 = (double) df.parse(data);
String num3 = df.format(data3);
}
catch(ParseException e) {
}
⑦ 어노테이션
@Override
⑧ StringTokenizer : String클래스의 split()을 사용하는것과 비슷한 개념. token화.
import java.util.StringTokenizer;
StringTokenizer st = new StringTokenizer("java:servlet:jdbc:spring:hadoop",":");
System.out.println(st.countTokens());//토근의 개수 리턴
while(st.hasMoreTokens()) { // StringTokenizer 내부 저장소에 token이 있으면 true 없으면 false 리턴
String token = st.nextToken(); // token을 리턴.
System.out.println(token);
}
⑨ Arrays
import java.util.Arrays;
int[] arr = {10,20,30,40,50};
Arrays.fill(arr,100); // 배열 요소를 특정 값으로 채우기
Arrays.equals(arr, arr2); // 배열값이 같은지 비교
Arrays.sort(arr); // 배열의 데이터 정렬(default : 오름차순)
Arrays.binarySearch(arr,50); // 배열에서 특정 값이 저장된 요소의 index
⑩ 향상된 for문
for(요소의 타입 요소를 저장할 변수:컬렉션을 참조하는 변수){
}
12. 컬렉션 : List, Map, Set을 생성하기 전에 저장될 요소의 타입을 미리정의
컬렉션 클래스<요소의 타입> 변수 = new 컬렉션 클래스<요소의 타입>();
<요소의 타입> : Generic
① List : 배열과 동일한 구조, 중복 가능. 주로 ArrayList 사용.
1) Vector : 무겁 Thread에 안전
import java.util.Vector;
Vector v = new Vector(); // 다른 타입도 저장가능. 5.0이전 사용
//=> Vector안에 저장되는 데이터의 타입을 제한(요소타입이 기본형인 경우 Wrapper타입으로 명시)
Vector<Integer> v = new Vector<Integer>(); // Generic으로 Vector의에 저장되는 요소의 타입을 명시
v.add(10); // 값 추가.
v.size(); // 현재벡터에 저장된 요소의 개수
v.capacity(); // 현재 벡터의 용량
v.get(0) // 값 read
Vector<String> v2 = new Vector<String>();
v2.add("aa");
for(String s:v2) {
System.out.print(s+" ");
}
2) ArrayList : 가볍 thread에 unsafe
import java.util.ArrayList;
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(10); // 값 추가.
list.size(); // 저장된 요소의 개수
list.get(0) // 값 read
3) 2차원 배열
import java.util.ArrayList;
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> row = new ArrayList<Integer>();
for(int i=0;i<3;i++) {
row.add(i);
}
ArrayList<Integer> row2 = new ArrayList<Integer>();
for(int i=3;i<7;i++) {
row2.add(i);
}
ArrayList<Integer> row3 = new ArrayList<Integer>();
for(int i=7;i<9;i++) {
row3.add(i);
}
list.add(row);
list.add(row2);
list.add(row3);
for(int i=0;i<list.size();i++) {
for(int j=0;j<list.get(i).size();j++) {
System.out.print(list.get(i).get(j)+"\t");
}
}
② Set : 집합. 합집합, 교집합가능. 중복이 불가능. 주로 HashSet 사용.
1) HashSet
import java.util.HashSet;
HashSet<String> set = new HashSet<String>(); // 생성
set.add("aa"); // 데이터 추가
set.add("bb");
set.add("cc");
set.add("dd");
set.add("ee");
set.add("aa"); // 중복불가
System.out.println("요소의 개수: " + set.size()); //5
// 데이터 추출
// set은 선형구조가 아니라 순서대로 읽어올 수 없다.
// 여러종류의 자료구조에 저장된 데이터를 내부에서 Iterator로 변환해서 읽을 수 있도록 지원
// HashSet -> Iterator
Iterator<String> it = set.iterator();
while(it.hasNext()) { // iterator안에 데이터가 있는 지 확인. boolean리턴
String element = it.next(); // Iterator에 저장된 요소 꺼내기
System.out.println("set에 저장된 요소 : "+element);
}
2) HashSet 교집합, 합집합
HashSet<String> set = new HashSet<String>();
set.add("aa");
set.add("bb");
set.add("cc");
set.add("dd");
set.add("ee");
set.add("ff");
//합집합 - Set을 생성할때 매개변수로 다른 Set을 전달
HashSet<String> set2 = new HashSet<String>(set);
set2.add("zz");
set2.add("yy");
set2.add("xx");
set2.add("aa");
//교집합
HashSet<String> set3 = new HashSet<String>();
set3.add("aa");
set3.add("dd");
set3.add("zz");
set.retainAll(set3); // 두 set의 교집합이 set에 새로 저장된다.
3) SortedSet
③ Map : key와 value. 주로 HashMap사용.
1) HashMap : Thread에 비안전, 빠름
HashMap<Integer,String> map1 = new HashMap<Integer, String>();
// key가 중복되면 마지막 작업한 내용으로 덮어쓴다.
map1.put(1, "aa");
map1.put(1, "bb");
map1.put(1, "cc");
System.out.println(map1.get(1)); //cc 마지막 값 리턴.
System.out.println(map1.size()); //1
HashMap<String, String> map2 = new HashMap<String, String>();
map2.put("a001", "aa");
map2.put("a002", "bb");
map2.put("a003", "cc");
map2.put("a004", "dd");
map2.put("a005", "ee");
map2.put("a006", "ff");
map2.put("a007", "gg");
map2.put("a008", "hh");
System.out.println(map2.size());
System.out.println(map2.get("2"));
//map에 저장된 데이터를 꺼내기
//1. map이 갖고 있는 키들을 set으로 변환
Set<String> keyList = map2.keySet();
//2. set에 저장된 key목록을 iterator로 변환하고
Iterator<String> it = keyList.iterator();
//3. iterator에서 key를 하나씩 꺼내서 get
while(it.hasNext()) {
String key = it.next();
String value = map2.get(key);
System.out.println(key+":"+value);
}
2) HashTable : Thread에 안전, 느림
3) Properties
13. I/O
Input용클래스 - _____InputStream (byte단위)
_____Reader (문자단위)
Output용클래스 - _____OutputStream (byte단위)
_____Writer (문자단위)
1) InputStream, PrintStream : byte 단위 입출력 처리
class System{
public static final InputStream in;
public static final PrintStream out;
}
InputStream myin = System.in;
PrintStream myout = System.out;
try {
while(true) {
int data = myin.read(); // 키보드로 입력한 단어를 읽어서 리턴.
myout.print((char)data+" "); // 입력받은 데이터는 int로 문자로 변환하여 출력.
//System.out.print((char)data+" "); // System.out = myout
if(data==13) // 개행문자가 오면 종료.
break;
}
}
catch(IOException e) { // read()는 예외처리가 필요.
e.printStackTrace();
}
2) InputStreamReader : 문자 단위 입출력 처리. 사용방법이 InputStream와 동일
InputStreamReader myin = new InputStreamReader(System.in); // 객체 생성만 다르다.
PrintStream myout = System.out;
try {
while(true) {
int data = myin.read();
myout.print((char)data);
if(data==13)
break;
}
}
catch(IOException e) {
e.printStackTrace();
}
3) File 클래스
File dir = new File("C:/java/test"); //액세스 하고 싶은 폴더나 파일의 경로 - 절대경로, 상대경로
//File dir = new File("C:\\java\\test");
File file = new File("test.txt"); // ROOT
System.out.println(file1); // toString()
System.out.println(file2); // 생성자에 입력값 출력.
file.canRead(); // 해당 파일을 읽을 수 있으면 true, 아니면 false 리턴.
file.canWrite(); // 해당 파일을 쓸 수 있으면 true, 아니면 false 리턴.
file.getAbsolutePath(); // 절대 경로 리턴
file.getName(); // 파일의 확장자를 포함한 이름 리턴
file.getParent(); // 파일 또는 폴더의 상위 경로 리턴
file.getPath(); // 상대경로 리턴
dir.isDirectory(); // 디렉토리이면 true, 아니면 false 리턴.
file.isDirectory();
dir.isFile(); // 파일이면 true, 아니면 false 리턴.
file.isFile();
dir.lastModified(); // 마지막 수정일자 리턴
// 폴더의 기본사이즈 : 4096
dir.length(); // 폴더 or 파일 크기 리턴
file.length();
file.setReadOnly(); // 읽기전용으로 변경.
file.setWritable(true); // 쓰기가능으로 변경.
File[] fileArr = file.listFiles(); // 파일객체 내부의 파일에 대한 파일객체 배열을 리턴
String[] fileName = file.list; // 파일객체 내부의 파일이름 배열 리턴
4) FileInputStream : byte 단위 파일 액세스
FileInputStream fis = null; // 인스턴스를 try안에서 생성 시 {}안에서만 사용할 수 있어
// 인스턴스만 생성 후 파일열기는 try 내부에서 진행.
try {
fis = new FileInputStream("src/data/test.txt");//1. 파일 열기 - FileNotFoundException 처리 필요
while(true) {
int data = fis.read(); // IOException 처리 필요
if(data == -1) { // 파일읽기가 끝나면 -1을 리턴한다.
break;
}
System.out.print((char)data);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
finally {
// 3. 파일 닫기 - 자원반납
//IO 작업을 하다가 오류가 발생하거나 정상적으로 처리된다고 하더라도 모두 자원을 반납해야하므로 finally 블럭에서 처리.
// input은 오류가 없는 output은 close를 안하면 파일에 output한 데이터가 write되기 전에 파일을 내부에서 종료한다.
try {
if(fis!=null) // 파일이 null로 파일열기에 실패할 경우 file close를 진행하면 안되므로 예외처리 진행.
fis.close(); // IO Exception 처리 필요.
}
catch(IOException e) {
e.printStackTrace();
}
}
5) FileReader : 문자 단위 파일 액세스. FileInputStream과 동일.
FileReader fr = null;
try {
fr = new FileReader("src/data/test.txt");
while(true) {
int data = fr.read();
if(data == -1) {
break;
}
System.out.print((char)data);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
finally {
try {
if(fr!=null)
fr.close();
}
catch(IOException e) {
e.printStackTrace();
}
}
6) FileWriter : 문자 단위 파일 쓰기. 파일이 존재하지 않으면 새로 만들어서 출력한다.
FileWriter fw = new FileWriter("src/data/output.txt");
// 두번째 매개변수가 없을 경우 default로 덮어쓰기을 진행한다.
FileWriter fw = new FileWriter("src/data/output.txt",true);
// 생성자에 두번째 매개변수가 true를 두면 apped모드 활성화된다.
fw.write(97);
fw.close();
7) BufferedReader : 버퍼를 이용하여 파일의 한 라인씩 읽을 수 있어 실행속도가 빨라 FileReader보다 많이 사용된다.
BufferedReader br = null;
// BufferedReader는 생성자 인자로 FileReader객체를 매개변수로 받는다.
// FileReader fr = null;
try {
br = new BufferedReader(new FileReader("src/io/InputStreamTest.java"));
// fr = new FileReader("src/data/test.txt");
// br = new BufferedReader(fr);
// FileReader 객체를 따로 생성해서 BufferedReader 매개변수에 전달할 수 있으나
// 코드를 줄이기 위해 한줄에 사용
while (true) {
String line = br.readLine(); // 한줄씩 읽는다.
if (line == null) { // 읽을 라인이 없다면 null을 리턴.
break;
}
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
<tip>
* toString 자동 생성: Source - Generate toString
* API 문서에서의 Deprecated : 미사용 권고