728x90

 

수업내용 정리 (Java)

 

1. 제네릭  (참고 / 참고2)

더보기
  • 일반화
  • 클래스나 메소드 내부에서 사용되는 객체의 타입 안정성을 높일 수 있다.
  • 반환값에 대한 타입 변환 및 타입 검사에 들어가는 노력을 줄일 수 있다.
  • 데이터 형식에 의존하지 않고, 하나의 값이 여러 다른 데이터 타입들을 가질 수 있도록 하는 방법
  • 클래스 내부에서 지정하는 것이 아닌 외부에서 사용자에 의해 지정되는 것
  • 클래스 자체가 아니라 클래스 내의 메소드 하나만 제네릭인 경우도 있다.
  • 기본 자료형은 사용할 수 없다. (ex: int, double 등)
  • ArrayList 등을 사용할 때 붙어있는 꺽새 괄호<>가 제네릭이다. (ex: ArrayList<String>)
  • 타입이 정해져있지 않다면 <T>를 적는다. (템플릿의 약자) / Object로 적으면 자료형이 안정성이 떨어진다.

 

fct(10);
fct('A');
fct("A");

void fct(T a) { … }
  • 알아서 int, char, String으로 생성된다.

 

ArrayList<String> list = new ArrayList<>();
//list.add(1);
list.add("1");
list.add("2");
for(String s : list) System.out.println(s);

ArrayList<Integer> listI = new ArrayList<>();
listI.add(3);
listI.add(4);
for(int s : listI) System.out.println(s);
  • 제네릭 타입을 String으로 적어서 ArrayList를 문자로 채우겠다고 약속을 했는데 숫자를 넣으면 에러가 난다.
  • 제네릭 타입을 Integer을 적고 안에 있는 값을 foreach int로 돌려도 값이 출력된다.
  • 클래스를 타입으로 적을 수 있다.

 

 

2. 컬렉션 프레임워크 (참고)

더보기
  • 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합을 의미
  • 데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현해 놓은 것
  • 컬렉션 프레임워크 주요 인터페이스는 List 인터페이스, Set 인터페이스, Map 인터페이스를 정의하고 있지만 List, Set 인터페이스는 Collection 인터페이스를 상속받고 Map 인터페이스는 별도 정의한다.
  •  
  • 컬렉션 프레임워크를 구성하는 모든 클래스는 제네릭으로 표현
출처: 주요 인터페이스 간의 상속 관계 <TCP school(참고)>
  • List <E>: 저장 순서 인정 / 중복값 허용 (ArrayList, LinkedList 등)
  • Set <E>: 저장 순서 비인정 / 중복값 비허용 (HashSet, TreeSet) (단, 내가 만든 클래스를 타입으로 받을 경우, 중복값을 제거해주지 않으므로 직접 equals랑 HashCode를 오버라이딩해주어야 중복값을 제거할 수 있다.)
  • Map <K, V>: 저장 순서 비인정 / 키: 중복값 비허용, 값: 중복값 허용 / 키(Key)와 값(Value)이 한 쌍 (HashMap, TreeMap 등)

 

 

3. List 계열

더보기
  • ArrayList<E>: 특징이 배열의 특징과 일치

장점: 데이터의 참조가 용이해서 빠른 참조가 가능하다.

단점: 저장소의 용량을 늘리는 과정에서 많은 시간이 소요되고, 데이터의 삭제에 필요한 연산과정이 매우 길다. (잦은 삽입/삭제에 오버헤드가 걸린다.)

  • LinkedList<E>: 특징이 리스트의 자료구조의 특징과 일치

장점: 저장소의 용량을 늘리는 과정이 간단하고, 데이터의 삭제가 매우 간단하다.

단점: 데이터의 참조가 다소 불편하다.

 

ArrayList<Integer> list = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<>();
List<Integer> list3 = new ArrayList<>();
Collection<Integer> list4 = new ArrayList<>();
  • 꺽새(제네릭)에 기본타입(ex: int) 불가
  • 뒷 꺽새는 타입을 안 적어도 되지만 꺽새는 적어야한다.
  • 부모타입인 List/Collection으로 ArrayList 생성 가능

 

list.add(10);
list.add(new Integer(20));
list.add(30);
  • new Integer 스킵 가능

 

System.out.println(list.size()+"개");
  • size를 통해 ArrayList 길이 출력 가능

 

list.remove(0);
  • 첫번째 인덱스(10) 삭제

 

for(int s : list) {
	System.out.println(s);
}

for(Integer s : list) {
	System.out.println(s);
}

for(int i=0; i<list.size(); i++) {
	System.out.println(list.get(i));
}
  • 세가지 모두 리스트 값을 출력한다.
  • Integer 타입이지만 int 타입에 값을 담아서 출력하는 방법도 가능하다.

 

 

4. Iterator (참고)

더보기
  • 반복자
  • 컬렉션 프레임워크(List, Set, Map, Queue)에서 값을 가져오거나 삭제할 때 사용
  • list.get()으로 값을 꺼내올 수 없는 Set에서 사용할 수 있다.
  • 장점

모든 컬렉션 프레임워크에 공통적으로 사용이 가능하다.  쉽게 값을 가져오거나 제거가 가능하다.

  • 단점

처음부터 끝까지의 단방향 반복만 가능하다. 값을 변경하거나 추가하는 것이 불가능하고, 대량의 데이터를 제어할 때 속도가 느리다.

  • 메소드

Iterator.hasNext(): 다음 값이 있으면 true, 아니면 false 값을 반환

Iterator.next(): 다음 값을 가져온다.

Iterator.remove(): next 시 가져왔던 값(현재 값)을 컬렉션에서 삭제한다. 반드시 Iterator.next() 다음에 사용!

 

 

Set<String> list = new HashSet<>();
list.add("first");
list.add("first");
list.add("third");
list.add("fourth");
  • 두번째 적은 first는 중복값이므로 Set으로 만든 list에 값이 저장되지 않는다. 따라서 값은 3개만 저장된다.

 

Iterator<String> ir = list.iterator();
while(ir.hasNext()){
	String curStr = ir.next();
	System.out.println("curStr: "+curStr);
	if(curStr.equals("third")) {
		ir.remove();	// 반복자의 현재 요소를 삭제
	}
}
  • while문의 조건에 ir.hasNext를 넣어 list에 다음 값이 있다면 true, 아니라면 false를 입력받아 반복문을 돌리거나 나간다.
  • 임시변수에 ir.next를 통해 현재 값을 저장한다.
  • if문의 조건에 삭제하고 싶은 값과 현재 값이 같은지 적고, 만약 맞다면 iterator의 현재 요소를 삭제하면 list에서도 삭제된다.

 

ir = list.iterator();
while(ir2.hasNext()){
	System.out.println(ir2.next());
}
  • 다시 반복하려고 하면 ir에 새로 지정해주어야 한다.
더보기
HashSet<Person> hSet = new HashSet<Person>();
hSet.add(new Person("최순이", 10));
hSet.add(new Person("최순이", 20));
hSet.add(new Person("갑돌이", 20));
hSet.add(new Person("갑돌이", 15));
hSet.add(new Person("최순이", 20));
hSet.add(new Person("갑돌이", 20));
System.out.println("데이터 수:" + hSet.size());
Iterator<Person> itr = hSet.iterator();
while (itr.hasNext()) {
	System.out.println(itr.next());
}
  • 내가 만든 클래스를 타입으로 주고 저장하면, 중복값이 제거되지 않는다. (클래스 내에서 오버라이딩 해주어야 한다.)
  • Iterator을 통해 값을 출력한다.

 

private String name;
private int age;

public Person(String name, int age) {
	this.name = name;
	this.age = age;
}

@Override
public String toString() {
	return name + "(" + age + "세)";
}

@Override
public boolean equals(Object obj) {
	Person p = (Person)obj;
	if(this.name.equals(p.name) && this.age == p.age) {
		return true;
	}
	return false;
}
@Override
public int hashCode() {
//		return age;	// 나이가 같은 사람끼리 모아두기
//		return name.hashCode();	// 이름이 같은 사람끼리 모아두기
	return age%3 + name.hashCode();
    // 나이가 같은 사람끼리(3그룹), 이름이 같은 사람끼리 모아두기
}

@Override
public int compareTo(Person p) {
	// 이름 길이, 알파벳 순 정렬+같은 길이 스킵 안 함
	if(name.length()>p.name.length()) return 1;
	else if(name.length()<p.name.length()) return -1;
	else {
		if(name.compareTo(p.name)>0) return 1;
		else if(name.compareTo(p.name)<0) return -1;		
}
  • 중복값을 제거하기 위해 equals와 hashCode를 오버라이딩했다.
  • equals 메소드 오버라이딩에서 받아올 변수가 Object로 받았기 때문에 (Person)을 통해 강제형변환을 해준다. 조건문에 같은 조건을 주고, 조건을 만족하면 true를 return하고 조건을 만족하지 못하면 false를 return한다.
  • Person 클래스에 implements Comparable했기 때문에 compareTo를 오버라이딩할 수 있다.

 

 

5. 예제

더보기
public class Main {
	public static void main(String[] args) {
		MemberArrayList mList = new MemberArrayList();
		Member lee = new Member(1001, "이순신");
		Member kim = new Member(1002, "김유신");
		Member kang = new Member(1003, "강감찬");
		Member hong = new Member(1004, "홍길동");
		Member hong2 = new Member(1004, "홍길동");
		
		mList.addMember(lee);
		mList.addMember(kim);
		mList.addMember(kang);
		mList.addMember(hong);
		mList.addMember(hong2);
		
		mList.showAllMember();
		mList.removeMember(kim.getId());
		mList.showAllMember();
	}
}
  • ArrayList를 이용한 멤버 목록

 

public class Member {
	private int id;
	private String name;
	
	public Member(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
    
	@Override
	public String toString() {
		return id+"\t"+name;
	}
}
  • Member 클래스

 

public class MemberArrayList {
	private ArrayList<Member> memberList;

	public MemberArrayList() {
		memberList = new ArrayList<>();
	}
	public MemberArrayList(int size) {
		memberList = new ArrayList<>(size);
	}
	
	public void addMember(Member member) {
		this.memberList.add(member);
	}
	
	public boolean removeMember(int id) {
		Iterator<Member> ir = memberList.iterator();
		while(ir.hasNext()) {
			Member member = ir.next();
			int tempId = member.getId();
			if(tempId == id) {
				memberList.remove(member);
				return true;
			}
		}
		System.out.println(id+"가 존재하지 않습니다.");
		return false; 
	}
	
	public void showAllMember() {
		System.out.println("============");
		System.out.println("id\tname");
		System.out.println("--  ----  --");
		for(Member m:memberList) {
			System.out.println(m);	// Member의 toString 생략
		}
		System.out.println("============");
		System.out.println();
	}
}
  • Member 클래스를 통해 만들어낸 객체들을 저장하고, 컨트롤타워에서 명령한 메소드가 담겨있는 ArrayList 클래스
  • 삭제는 Iterator을 통해 메소드를 작성했다. (독해는 위의 4. Iterator에서 적어두었다.)

 

 

 


 

질문한 내용이나 어려웠던 점 메모

1. Iterator

  • 보면 알겠는데 혼자 아무것도 없이 해보려고 하면 뭐였지..하면서 기억나지 않아서 여러번 예제를 만들거나 같은 예제를 계속 작성해보면서 연습해봐야할 것 같다.

 


 

전체 피드백

  • 예제를 많이 해본 것과 안 해본 것의 차이겠지만 아직은 Iterator보다는 for문이 조금 더 편한 것 같다..
  • 건강으로 인해 컨디션이 나빠서 자꾸 수업시간에 집중할 수 없었다.. ㅠ

 


728x90