ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바기초개념 다시잡기 자바의정석 - 예외처리/컬렉션프레임/제네릭/쓰레드
    자바 기초 2021. 8. 2. 18:57

    남궁성님의 자바의 정석 - 기초편 유투브 참조!

    1. 오류 및 예외

    • 프로그램 오류에는 컴파일/런타임/논리적 에로로 나뉜다
    1. 컴파일에러 - 자바프로그램(이클립스)가 이해하지 못하는 에러(구문-문법/번역/최적화)
    2. 런타임에러 - 실행중 발생하는 에러 (컴파일시에는 에러가 없지만 프로그램이 실행되면서 특정 상황이나 특정값이 들어갈때등 나타나는 에러 -> A(1) / B(0) 일때 문법은 맞으나 0으로 나눌 수 없으니 런타임 뜸)
    3. 논리적에러 - 작성의도와 다르게 동작되는 에러 

     

    • 자바의 런타임 에러는 크게 두개로 나뉜다
    1. 에러(error) - 코드에 의해서 수습될 수 없는 '심각한' 오류
    2. 예외(exception) - 코드에 의해서 수습이 가능한 '미약한' 오류
    • 즉 에러는 어쩔수 없지만 예외처리가 가능한 것은 개발자로써 해야한다
    • 예외처리로 비정상 종료를 막고 프로그램이 계속해서 정상적으로 실행되도록 유지해야한다

     

    • 예외처리는 Exception과 RuntimeExcetion으로 구분
    1. Exception - 사용자의 실수와 같은 외적인 요인으로 발생
    2. RuntimeExcetion - 프로그래머의 실수로 발생

    1. IOException - 입출력예외
    2. ClassNotFoundException - 클래스를 찾을 수 없음
    3. ArithmeticException - 산술계산예외
    4. ClassCastException - 형변환 예외
    5. NullPointerException - 어떤 변수 또는 객체가 null인데 호출할 때
    6. IndexOutOfBoundsException - 배열범위벗어남
    • 그외 예외처리시 자주 쓰는 것들
    1. printStackTrace() - 예외발생시 호출스택에 있었던 메서드의 정보와 예외 메세지를 화면에 출력
    2. getMessage() - 발생한 예외클래스의 인스턴스에 저장된 메세지를 얻을 수 있음

    2. 예외처리하기

    • 예외처리는 보통 'try-catch'문으로 처리한다

     

     

     

     

    3. 컬렉션 프레임워크

    • 자바의 객체지향 다음으로 가장 중요한 부분
    • 여러 자주쓰는 객체 혹은 데이터 등을 모아 표준화/정형화를 시켜놓은 것. 일일이 코드를 짤 필요없이 자주 쓰는 것들은 컬렉션 프레임워크를 호출해서 쓰면 된다(Vector/ArrayList,Hash etc)
    • 컬렉션 프레임워크의 핵심은 다수의 데이터를 다루기 위한 것(List/Set/Map)

    색이 들어가있는 콜렉션들, 즉 추가,검색,삭제가 많이 쓰인다

    3-1 List 인터페이스

    • 순서가 정해져 있으며 중복이 허용 된다
    • ArrayList/LinkedList가 핵심이다

    3-1-1 ArrayList

    • 기존 Vector를 개선했고 동기화처리가 가능하며 배열을 기반으로 동작된다
    • ArrayList 안의 객체를 '모두' 삭제하려면 반드시 총 사이즈 - 1 을 해야한다 왜냐하면 remove(삭제)의 경우는 데이터를 지우는것이아니라 있던 자리를 null로 대체하고 한칸씩 밀려 올라가기 때문이다. 다 지우고싶으면 반드시 끝에서부터 해야한다
    public class Ex_1 {
    	public static void main(String[] args) {
    		ArrayList list1 = new ArrayList(10);
    		list1.add(5);
    		list1.add(4);
    		list1.add(3);
    		list1.add(1);
    		list1.add(2);
    		System.out.println(list1);
    		
    		ArrayList list2 = new ArrayList(list1.subList(0, 2));
    		System.out.println(list2);
    		
    	}
    }
    [5, 4, 3, 1, 2]
    [5, 4]
    
    
    		Collections.sort(list1);
    		System.out.println(list1);
    [1, 2, 3, 4, 5]
    
    
    		list1.add("B");
    		list1.add(1,"S");
    		System.out.println(list1);
    [1, S, 2, 3, 4, 5, B]
    
    
    //set은 변경
    		list1.set(2, "DD");
    		System.out.println(list1);
    [1, S, DD, 3, 4, 5, B]
    
    
    
    		list1.add(0,"1");
    		System.out.println(list1);
    		System.out.println("index= "+ list1.indexOf("1"));
    [1, 1, S, DD, 3, 4, 5, B]
    index= 0  
    
    
    		list1.remove(3);
    		System.out.println(list1);
            list1.remove(new Integer(3));
    		System.out.println(list1);
    [1, 1, S, 3, 4, 5, B]
    [1, 1, S, 4, 5, B]

    처음부터 지우면 스택이 올라가기때문에 다 지울 수 없다
    반드시 이런 로직으로 지워야 다 지워진다

     

    3-1-2 LinkedList

    • 배열 구조가 간단하고 데이터를 읽는 시간이 짧다는 장점이 있지만 크기 변경 불가(변경이 필요하면 새 배열을 생성 후 데이터를 옮기는 구조로 해야한다)
      1) 더 큰 배열 생성 -> 2) 원 데이터 복사 -> 3) 참조 변경
    • 배열의 단점을 보완한 기능

     

     

    *컬렉션 프레임 워크 사용시에 데이터를 접근하는데 사용하는 인터페이스 (Iterator)

     

     

    3-2 HashSet

    • Set 인터페이스의 가장 중요한 요소 중 하나로 순서를 유지하지않고 중복을 허용하지 않는다.
      (순서 유지는 LinkedHashSet)
    public class Ex_2 {
    	public static void main(String[] args) {
    		Object[] arr = {"1", 1, "2","2","3","3","4","4"};
    		Set set = new HashSet();
    		
    		for (int i=0; i<arr.length; i++) {
    			System.out.println("arr[i]= " + arr[i]);
    			System.out.println("set.add(arr[i])= " + set.add(arr[i]));
    		}
    		System.out.println(set);
    	}
    }
    arr[i]= 1
    set.add(arr[i])= true
    arr[i]= 1
    set.add(arr[i])= true
    arr[i]= 2
    set.add(arr[i])= true
    arr[i]= 2
    set.add(arr[i])= false
    arr[i]= 3
    set.add(arr[i])= true
    arr[i]= 3
    set.add(arr[i])= false
    arr[i]= 4
    set.add(arr[i])= true
    arr[i]= 4
    set.add(arr[i])= false
    [1, 1, 2, 3, 4]
    
    		Iterator it = set.iterator();
    		while(it.hasNext()) {
    			System.out.println(it.next());
    		}
    1
    1
    2
    3
    4
    
    
    public class Ex_2 {
    	public static void main(String[] args) {
    		Set set = new HashSet();
    		
    		for (int i=0; set.size() < 6; i++) {
    			int num = (int)(Math.random()*45) + 1;
    			set.add(num);
    		}
    		List list = new LinkedList(set); //*일반 리스트는 정수만 가능
    		Collections.sort(list);
    		System.out.println(list);
    	}
    }
    [17, 30, 33, 38, 41, 45]

     

     

    3-3 HashMap 

    • Map 인터페이스중 하나로 키와 값으로 구현 됨
    • 순서에 상관없이 저장 가능하고 중복은 키 제외 값은 중복 가능, 동기화 불가능 (순서 유지 -> LinkedHashMap)
    • 해싱 기법으로 데이터를 저장하기때문에 키와 값으로 빠르게 검색이 가능
    public class Ex_3 {
    	public static void main(String[] args) {
    		HashMap map = new HashMap();
    		map.put("aaa", "1234");
    		map.put("bbb", "1111");
    		System.out.println(map);
    		map.put("bbb", "1234");
    		System.out.println(map);
            
    {aaa=1234, bbb=1111}
    {aaa=1234, bbb=1234}
    
    
    
    
    		HashMap map = new HashMap();
    		map.put("aaa", "1234");
    		map.put("bbb", "1111");
    		map.put("bbb", "1234");
    		
    		Scanner sc = new Scanner(System.in);
    		
    		while(true) {
    			System.out.println("Enter your ID/PW.>>");
    			System.out.println("ID:");
    			String id = sc.nextLine().trim(); //trim() -> 공백제거
    			
    			System.out.println("PW:");
    			String pw = sc.nextLine().trim();
    			System.out.println();
    			
    			if(!map.containsKey(id)) {
    				System.out.println("Not found. Try again!>>>");
    				continue;
    			}
    			if(!(map.get(id)).equals(pw)) {
    				System.out.println("The password is incorrect. Try again!>>>");
    			} else {
    				System.out.println("ID/PW are correct!");
    				break;
    			}
    		}
    	}
    }
    Enter your ID/PW.>>
    ID:
    ccc
    PW:
    1111
    
    Not found. Try again!>>>
    Enter your ID/PW.>>
    ID:
    bbb
    PW:
    1234
    
    ID/PW are correct!
    
    
    
    
    		HashMap map = new HashMap();
    		map.put("VIC", 95);
    		map.put("CHA", 85);
    		map.put("KIM", 55);
    		map.put("MIN", 77);
    		map.put("RYU", 65);
    		
    		Set set = map.entrySet(); //map에 저장된 모든(entry) 키/값 들고옴
    		Iterator it = set.iterator();
    		
    		while (it.hasNext()) {
    			Map.Entry e = (Map.Entry)it.next(); //entrySet과 같은 기능으로 객체처럼 쓸때
    			System.out.println("Name: "+e.getKey()+", Point: "+e.getValue());
    		}
    		
    		set = map.keySet();
    		System.out.println("Student List: " +set);
    		
    		Collection values = map.values();
    		it = values.iterator();
    		
    		int total = 0;
    		while(it.hasNext()) {
    			Integer i = (Integer)it.next();
    			total += i;
    		}
    		System.out.println("Total point: "+total);
    		System.out.println("Average: "+(float)total/set.size());
    		System.out.println("Highest Point: "+Collections.max(values));
    		System.out.println("Highest Point: "+Collections.min(values));
    	}
    }
    Name: VIC, Point: 95
    Name: MIN, Point: 77
    Name: CHA, Point: 85
    Name: KIM, Point: 55
    Name: RYU, Point: 65
    Student List: [VIC, MIN, CHA, KIM, RYU]
    Total point: 377
    Average: 75.4
    Highest Point: 95
    Highest Point: 55
    
    
    
    		//단어카운팅
    		String[] data = {"A","A","K","A","K","D","D","D","D","Z","C","C","T","T"};
    		HashMap map = new HashMap();
    		
    		//map 키 유무 체크후 삽입, 거기에 맞게 value 삽입
    		//없으면 data의 값이 키로 가고 value=1 로 map에 저장됨
    		//그다음부터 data값이 중복되면 그 value+1이 됨
    		for (int i=0; i<data.length; i++) {
    			if(map.containsKey(data[i])) {
    				int value = (int)map.get(data[i]);
    				map.put(data[i], value+1);
    			} else {
    				map.put(data[i], 1);
    			}
    		}
    		Iterator it = map.entrySet().iterator();
    		while(it.hasNext()) {
    			Map.Entry e = (Map.Entry) it.next();
    			int value = (int)e.getValue();
    			System.out.println(e.getKey()+" : "+printBar('*', value)+" "+value);
    		}
    	}
    
    	public static String printBar(char ch, int value) { 
    		char[] bar = new char[value]; 
    
    		for(int i=0; i < bar.length; i++) { 
    			bar[i] = ch; 
    			System.out.println("bar="+(Arrays.toString(bar)));
    			System.out.println("ch="+ch);
    		} 
    
    		return new String(bar); 	// String(char[] chArr)
    	}
    }

     

     

    4. 제네릭스

    • 컴파일시 타입을 체크해주는 기능 -> 자바 특성상 컴파일시에는 형변환을 걸러낼수가없다. 실행은 되나 타입이 안맞으니 ClassCastException을 띄우는 경우가 자주 나오는데 이를 해결 해준다
    • 여러종류는 <Object> 라고 쓰고 찾을때 원하는 형태를 넣으면 된다
    • 타입체크와 형변환을 생략가능하게 만들므로 코드가 간결해진다. 
    • 타입을 의미하는 <T> 혹은 엘리멘트를 의미하는 <E>를 많이 쓴다
    • 보통 제네릭스를 쓸때에는 타입변수(T,E 등등) 대신 실제 타입을 지정한다 
      ArrayList<Tv> tvList = new ArrayList<Tv>();
    • 제네릭스에도 다형성이 적용 가능하다. 제네릭 타입에 부모가 들어가면 부모와 상속된 모든 자식들을 타입으로 쓸 수 있다
    class Student {
    	String name ="";
    	int ban;
    	int no;
    	
    	public Student(String name, int ban, int no) {
    		this.name = name;
    		this.ban = ban;
    		this.no = no;
    	}
    }
    public class Ex_1 {
    	public static void main(String[] args) {
    		ArrayList<Student> list = new ArrayList<Student>();
    		list.add(new Student("Kim", 1, 1));
    		list.add(new Student("Cha", 1, 3));
    		list.add(new Student("Vic", 3, 6));
    		
    		Iterator<Student> it = list.iterator();
    		while(it.hasNext()) {
    			System.out.println(it.next().name);
    		}
    	}
    }
    Kim
    Cha
    Vic
    
    		for (int i=0; i<list.size(); i++) {
    			System.out.println(list.get(i).name+list.get(i).ban+list.get(i).no);
    		}
    Kim11
    Cha13
    Vic36
    
    class Student {
    	String name ="";
    	int ban;
    	int no;
    	int kor;
    	
    	public Student(String name, int ban, int no, int kor) {
    		this.name = name;
    		this.ban = ban;
    		this.no = no;
    		this.kor = kor;
    	}
    
    	@Override
    	public String toString() {
    		return "ban=" + ban + ", no=" + no + ", kor=" + kor;
    	}
    }
    public class Ex_1 {
    	public static void main(String[] args) {
    		HashMap<String, Student> map = new HashMap<String, Student>();
    		map.put("Kim", new Student("Kim", 1, 1, 76));
    		
    //		System.out.println(map.get("Kim").name+map.get("Kim").ban);
    		Iterator<Map.Entry<String, Student>> it = map.entrySet().iterator();
    		while(it.hasNext()) {
    			Map.Entry<String, Student> e = (Map.Entry<String, Student>) it.next();
    			System.out.println(e.getKey()+" "+e.getValue().toString());
    		}
    	}
    }
    Kim ban=1, no=1, kor=76
    • 제한된 제네릭도 구현 가능 <T extends A> --> A의 자손만 타입으로 지정 가능

     

    5. 네트워크와 쓰레드

    -네트워크 지식 및 네트워크 통신관련은 아래 블로그를 참조!

    https://post.naver.com/viewer/postView.naver?volumeNo=7506644&memberNo=30800755&navigationType=push

    • 쓰레드는 프로세스와 항상 같이 묶어서 개념을 잡아야한다.
    • 프로세스는 실행중인 프로그램이며 자원과 쓰레드로 구성된다.
    • 쓰레드는 그 프로그램안에서 실제 작업을 수행하는 일꾼이라고 보면 된다. 모든 프로세스는 최소한 하나의 쓰레드를 가지고 있다. (싱글/멀티 쓰레드로 나뉨)
    • 하나의 새 프로세스를 생성하는것보다 하나의 새 쓰레드를 생성하는것이 더 적응 비용이 든다

    멀티 쓰레드의 장-단점

    • 상속(extends Thread) 하거나 인터페이스(Runnable)을 구현하면 된다. 
Designed by Tistory.