Notice
Recent Posts
Recent Comments
관리 메뉴

Developer Gonie

[4주차] 67. 컬렉션, List 인터페이스를 상속받아 구현된 ArrayList 타입(순서,index O, 중복데이터 O)*** 본문

K-DigitalTraining 강의/1. Java

[4주차] 67. 컬렉션, List 인터페이스를 상속받아 구현된 ArrayList 타입(순서,index O, 중복데이터 O)***

이대곤 2022. 6. 2. 12:38

* ArrayList 클래스란?

  List 인터페이스를 구현하여 만들어진 클래스로, 객체만을 저장 가능하며

  List의 특징을 그대로 상속받아 순서(index)가 있고, 중복 데이터의 입력이 가능하다.

출처: 생활코딩

* 원소들을 간편히 원하는대로 출력하고 싶은 경우 오버라이딩 해줘야 하는 메소드

   ArrayList의 조상클래스로 추상클래스인 AbstractCollection이 있는데,

   이 클래스가 Object로부터 상속받은 toString을 오버라이딩 해두었고

   이 메소드를 ArrayList가 물려받았다.

    ArrayList의 toString() 메소드는 [요소1, 요소요소3, , ,   ] 형태를 만들어주며

   이후에 각 요소의 toString() 메소드를 호출해 반환받은 값을 위 자리에 대치해준다.
   따라서 뭔가 원하는 출력 포멧이 있다면 사용자 정의 클래스 내부에 toString() 메소드를 오버라이딩 해주자.
   이때 사용자 정의 클래스에서 오버라이딩 되는 toString() 메소드는 Object 클래스로부터 상속받은 것이다.

 

* 배열(Array)과 ArrayList의 구분되는 차이점

  배열

- 연속된 메모리의 공간을 가진다.
- 제네릭을 사용할 수 없다.
- 상대적인 단점,
  크기가 고정이라 컴파일 전에 크기를 정해줘야 하며, 어떤 요소를 삭제하더라도 이를 빈 공간으로 남겨둬야 한다.

 

ArrayList
- 크기를 동적으로 변화시킬 수 있다.
- 제네릭을 사용할 수 있다.
- 상대적인 단점,
  중간에서 일어나는 삽입/삭제 연산이 느린데, 삽입을 예시로 들면 일단 배열의 크기를 하나 늘리고 주소를 한칸씩 뒤로
  복사해서 옮기는 과정이 필요하다. 삭제시에는 삭제 후 한칸씩 앞으로 복사해서 옮기는 과정이 있다.
  반면 맨 뒤에서 이뤄지는 삽입과 삭제는 효율에 큰 영향을 미치지 않음 

 

* ArrayList와 LinkedList의 구분되는 차이점

  ArrayList

- 상대적인 단점,
  중간에서 일어나는 삽입/삭제 연산이 느린데, 삽입을 예시로 들면 일단 배열의 크기를 하나 늘리고 주소를 한칸씩 뒤로
  복사해서 옮기는 과정이 필요하다. 삭제시에는 삭제 후 한칸씩 앞으로 복사해서 옮기는 과정이 있다.
  반면 맨 뒤에서 이뤄지는 삽입과 삭제는 효율에 큰 영향을 미치지 않음
  아무튼 ArrayList는 중간에서 이뤄지는 삽입/삭제가 많다면 효율이 떨어진다. 

 

  LinkedList

- 중간에서 일어나는 삽입/삭제 연산시, 새로운 노드를 생성해 중간의 연결을 끊어 가리키는 주소만 변경해주면 됨
   ArrayList처럼 전체 데이터를 한칸씩 밀고 옮겨오고 하는 과정이 없음 

- 상대적인 단점,
  각 노드가 다음 노드의 위치정보만을 가지고 있어서 index가 없어 순차접근만 가능하여 get 메소드 사용시 효율이
  상대적으로 떨어짐

 

출처 : http://changpd.blogspot.com/2014/08/arraylist-linkedlist-java.html

 

정적인 데이터를 활용하면서 조회가 빈번하다면 ArrayList를 사용하는 것이 좋고,

동적으로 추가/삭제 요구사항이 빈번하다면 LinkedList를 사용하는 것이 좋다.

 

* ArrayList와 Vector의 차이점

  이 둘은 list 인터페이스를 상속받아 index를 가지고 동적인 배열을 관리할 수 있다는 공통점이 있는데,
  다음과 같은 다른점이 있다.

 

  가장 중요한 차이점으로 Vector는 메소드들이 동기화 되어있어 멀티쓰레드 환경에서 바로 사용될 수 있고,
  ArrayList는 메소드들이 동기화 되어 있지 않아 일일이 synchronized 해주며 임계영역을 설정해줘야 한다.
  이런 차이점으로 멀티쓰레드 환경에서는 Vector를 사용하되, 단일 쓰레드 환경에서는 ArrayList를 쓰는게 좋다.

 

  또 다른 차이점으로 Vector는 최고 index 도달시 현재 배열의 크기의 100%를 증가시키고
  ArrayList는 현재 배열의 크기의 50%를 증가시킨다고 한다.

 

* ArrayList와 LinkedList의 차이점

 

 

* ArrayList에서 자주 사용되는 메소드

ArrayList<타입> list = new ArrayList<타입>();

list.size()		// 원소의 개수 반환

list.add(객체);		// 객체를 맨 뒤에 추가 
list.add(index,객체);	// index 자리에 객체를 삽입, index 위치부터 뒤의 원소를 싹다 한칸씩 밀고

list.set(index, 객체)	// index 위치의 객체를 파라미터로 넘겨준 객체로 대체 

list.remove(index)	// index 위치의 원소를 제거

list.indexOf(객체)	// 객체가 위치한 인덱스를 반환, 존재하지 않으면 -1 반환

list.contains(객체)	// 객체의 존재여부 true/false 반환

list.get(index)		// index 에 위치한 객체 반환
		
// 확장 for문을 이용한 전체 원소 출력
for(타입 변수 : list) {
	System.out.println(변수);
}

//Enumeration 타입을 이용해 모든 원소를 출력하는 방법
Enumeration<타입> e = Collections.enumeration(list); // Vector와 달리 ArrayList, HashSet은 elements() 메소드를 가지지 않아 Collections 클래스의 enumeration() 메소드를 이용해야 함, 이 클래스는 list set 공통 상위의 인터페이스인 Collection과 다름  
while (e.hasMoreElements()) {
	System.out.println(e.nextElement());
}

// Iterator 타입을 이용해 출력하는 방법
Iterator<타입> it = list.iterator();
while(it.hasNext()) {
	타입 j = it.next();
	System.out.println(j + " ");
}

기본데이터 타입 8가지 값을 ArrayList에 저장하여 관리하는 코드

import java.util.ArrayList;
import java.util.Scanner;

public class Ex09_02_ArrayList2 {
	public static void main(String[] args) {
	
		// 타입지정은 클래스 이름만 가능해서 기본자료형 8가지는 레퍼클래스의 이름을 적어줘야 한다. 
		// ArrayList list = new ArrayList(); 와 같이 타입을 지정하지 않고도 바로 사용이 가능하나 경고문이 뜸
		ArrayList<Integer> list = new ArrayList<Integer>();
		
		//요소를 추가하는 연산
		list.add(5);
		list.add(3);
		list.add(6);
		list.add(6); // 중복 데이터 허용
		
		// 원소의 개수를 출력, 여기선 size()가 길이구하는 메소드(배열에서는 length를 사용했음, 시작부터 크기가 정해져 멤버변수로 길이를 바로 가져옴)
		System.out.println("size : " + list.size());
		System.out.println("list : " + list.toString());
		System.out.println();
		
		// index 1 자리에 7을 끼워넣는 연산으로 원래 있던 애들은 뒤로 한칸씩 밀림
		list.add(1, 7);
		System.out.println("list : " + list.toString());
		System.out.println();
		
		// index 1 자리의 것을 9로 변경하는 연산
		list.set(1, 9);
		System.out.println("list : " + list.toString()); 
		System.out.println();

		// index 0 자리의 것을 제거하는 연산
		list.remove(0);
		System.out.println("list : " + list.toString()); 
		System.out.println();
		
		// 숫자 3이 위치한 index 를 얻는 연산, String클래스의 indexOf랑 같음 기능 : 없으면 -1, 있으면 0이랑 같거나 큰 값 반환
		int index = list.indexOf(3); 
		System.out.println("3이 위치한 index : " + index);
		System.out.println();
		
		// 숫자 5의 존재여부를 확인하는 연산
		boolean isHas1 = list.contains(5);
		System.out.println("5의 존재여부 : " + isHas1);
		System.out.println();
		
		// 요소에 접근하는 get() 메소드
		System.out.println(list.get(0));
		System.out.println(list.get(1));
		System.out.println(list.get(2));
		System.out.println(list.get(3));
		System.out.println();
		
		// 확장 for문을 이용한 전체 원소 출력
		for(int num : list) {
			System.out.println(num);
		}
		System.out.println();

		// ArrayList의 요소들을 한번에 출력하는 방법 및 원리
		// ArrayList의 조상클래스로 추상클래스인 AbstractCollection이 있는데 이 클래스가 Object로부터 상속받은 toString을 오버라이딩 해두었고
		// 그 기능은 리스트 각 요소의 toString() 을 호출해 반환값을 받아가지고 [, ,,,]에 넣어서 이걸 최종적으로 반환함
		System.out.println(list); // 자동으로 list.toString()이 호출
		System.out.println(list.toString());
	}
}
size : 4
list : [5, 3, 6, 6]

list : [5, 7, 3, 6, 6]

list : [5, 9, 3, 6, 6]

list : [9, 3, 6, 6]

3이 위치한 index : 1

5의 존재여부 : false

9
3
6
6

9
3
6
6

[9, 3, 6, 6]
[9, 3, 6, 6]

String 클래스의 객체를 ArrayList에 저장하여 관리하는 코드

import java.util.ArrayList;
import java.util.Scanner;

public class Ex09_02_ArrayList2 {
	public static void main(String[] args) {

		ArrayList<String> list = new ArrayList<String>();
		
		//요소를 추가하는 연산
		list.add("수영");
		list.add("효연");
		list.add("써니");
		list.add("수영"); // 중복 데이터 허용
		
		// 원소의 개수를 출력, 여기선 size()가 길이구하는 메소드(배열에서는 length를 사용했음, 시작부터 크기가 정해져 멤버변수로 길이를 바로 가져옴)
		System.out.println("size : " + list.size());
		System.out.println("list : " + list.toString());
		System.out.println();
		
		// index 1 자리에 '태연'를 끼워넣는 연산으로 원래 있던 애들은 뒤로 한칸씩 밀림
		list.add(1, "태연");
		System.out.println("list : " + list.toString());
		System.out.println();
		
		// index 1 자리의 것을 '윤아'로 변경하는 연산
		list.set(1, "윤아");
		System.out.println("list : " + list.toString()); 
		System.out.println();

		// index 1 자리의 것을 제거하는 연산
		list.remove(1);
		System.out.println("list : " + list.toString()); 
		System.out.println();

		// 여러개 존재해도 가장 첫번째로 찾아진 "수영"을 제거하는 연산
		list.remove("수영");
		System.out.println("list : " + list.toString());
		System.out.println();

		// '써니'가 위치한 index 를 얻는 연산, String클래스의 indexOf랑 같음 기능 : 없으면 -1, 있으면 0이랑 같거나 큰 값 반환
		int index = list.indexOf("써니"); 
		System.out.println("써니가 위치한 index : " + index);
		System.out.println();
		
		// '윤아'의 존재여부를 확인하는 연산
		boolean isHas1 = list.contains("윤아");
		System.out.println("윤아의 존재여부 : " + isHas1);
		System.out.println();
		
		// 요소에 접근하는 get() 메소드
		System.out.println(list.get(0));
		System.out.println(list.get(1));
		System.out.println(list.get(2));
		System.out.println();
		
		// 확장 for문을 이용한 전체 원소 출력
		for(String s : list) {
			System.out.println(s);
		}
		System.out.println();

		// ArrayList의 요소들을 한번에 출력하는 방법 및 원리
		// ArrayList의 조상클래스로 추상클래스인 AbstractCollection이 있는데 이 클래스가 Object로부터 상속받은 toString을 오버라이딩 해두었고
		// 그 기능은 리스트 각 요소의 toString() 을 호출해 반환값을 받아가지고 [, ,,,]에 넣어서 이걸 최종적으로 반환함
		System.out.println(list);					// 자동으로 list.toString()이 호출
		System.out.println(list.toString());
	}
}
size : 4
list : [수영, 효연, 써니, 수영]

list : [수영, 태연, 효연, 써니, 수영]

list : [수영, 윤아, 효연, 써니, 수영]

list : [수영, 효연, 써니, 수영]

list : [효연, 써니, 수영]

써니가 위치한 index : 1

윤아의 존재여부 : false

효연
써니
수영

효연
써니
수영

[효연, 써니, 수영]
[효연, 써니, 수영]

사용자 정의 클래스의 객체를 ArrayList에 저장하여 관리하는 코드

import java.util.ArrayList;
import java.util.Scanner;

class Person {
	private String id;
	private String pw;

	Person(String id, String pw) {
		this.id = id;
		this.pw = pw;
	}

	void setId(String id) {
		this.id = id;
	}

	void setPw(String pw) {
		this.pw = pw;
	}
	
	String getId() {
		return id;
	}
	
	String getPw() {
		return pw;
	}
	
	public String toString() {
		return id + ":" + pw;
	}
}

public class Ex09_03_ArrayList {
	public static void main(String[] args) {
		ArrayList<Person> list = new ArrayList<Person>();

		Person p1 = new Person("kim", "1234");
		Person p2 = new Person("park", "7777");
		Person p3 = new Person("choi", "9876");
		
		list.add(p1);
		list.add(p2);
		list.add(p3);
		list.add(new Person("choi", "9876"));
		
		System.out.println(list.size());
		System.out.println(list);
		System.out.println("------------------");
			
		for(int i = 0; i<list.size(); i++) {
			Person p = list.get(i); // 주소를 받음
			System.out.println(p); // 뒤에 자동으로 .toString()이 붙는데 오버로딩 해둔게 불림
		}
	}
}
4
[kim:1234, park:7777, choi:9876, choi:9876]
------------------
kim:1234
park:7777
choi:9876
choi:9876

조상클래스 타입으로 ArrayList를 선언해 자손객체를 저장하여 관리하는 코드

package 자바정리;

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		ArrayList<Person> list = new ArrayList(); // Person 타입을 사용하면 이의 자식은 Doctor, Patient 객체를 넣을 수 있음
		
		Scanner sc = new Scanner(System.in);
		
		do {
			System.out.print("1.의사 2.환자   번호선택 >>");
			int selection = sc.nextInt();
			
			String name;
			int age;
			String hospital;
			String subject;
			String disease;
			
			if(selection == 1) {
				System.out.print("이름입력:" );
				name = sc.next();
				
				System.out.print("나이입력:" );
				age = sc.nextInt();
				
				System.out.print("병원명입력:" );
				hospital = sc.next();
				
				System.out.print("진료과목입력:" );
				subject = sc.next();
				
				Doctor d = new Doctor(1, name, age, hospital, subject);
				
				list.add(d);
			}
			else if(selection == 2) {
				System.out.print("이름입력:" );
				name = sc.next();
				
				System.out.print("나이입력:" );
				age = sc.nextInt();
				
				System.out.print("질병명입력:" );
				disease = sc.next();
				
				Patient p = new Patient(2, name, age, disease);
				
				list.add(p);
			}
			
			System.out.print("계속?");
			if(sc.next().equals("n")) {
				System.out.println();
				break;
			}
			
			System.out.println();
			
		}while(true);
		
		System.out.println("ArrayList 사용한 결과");
		for(int i = 0; i< list.size(); i++) {
			Object obj = list.get(i);
			System.out.println(i + ":" + obj.toString());
		}
		
		System.out.println();
		System.out.print("검색할 번호입력(1.의사 2.환자)  >>");
		int searchNo = sc.nextInt();
		
		System.out.print("검색할 이름입력:");
		String searchName = sc.next();
		
		boolean isFound = false;
		
		for(int i = 0; i< list.size(); i++) {
			Person p = list.get(i);
			if(p.getNo() == searchNo) {
				if(p.getName().equals(searchName)) {
					isFound = true;
					System.out.println(p.toString());
				}
			}
		}
		
		if(!isFound) {
			System.out.println("찾는 이름이 없습니다."); 
		}
	}
}
package 자바정리;

public class Person {
	private int no;
	private String name;
	private int age;
	
	public Person(int no, String name, int age) {
		this.no = no;
		this.name = name;
		this.age = age;
	}
	
	int getNo() {
		return this.no;
	}
	
	String getName() {
		return this.name;
	}
	
	int getAge() {
		return this.age;
	}
}
package 자바정리;

public class Doctor extends Person {
//	private int no;
//	private String name;
//	private int age;
	private String hospital;
	private String subject;
	
	public Doctor(int no, String name, int age, String hospital, String subject) {
		super(no, name, age);
		this.hospital = hospital;
		this.subject = subject;
	}
	
	public String toString() {
		return getNo() + ", " + getName() + ", " + getAge() + ", " + hospital + ", " + subject;
	}
}
package 자바정리;

public class Patient extends Person {
//	private int no;
//	private String name;
//	private int age;
	private String disease;

	public Patient(int no, String name, int age, String disease) {
		super(no, name, age);
		this.disease = disease;
	}
	
	public String toString() {
		return getNo() + ", " + getName() + ", " + getAge() + ", " + disease;
	}

}
1.의사 2.환자   번호선택 >>1
이름입력:kim
나이입력:33
병원명입력:중앙
진료과목입력:방사선
계속?y

1.의사 2.환자   번호선택 >>2
이름입력:lee
나이입력:44
질병명입력:당뇨
계속?n

ArrayList 사용한 결과
0:1, kim, 33, 중앙, 방사선
1:2, lee, 44, 당뇨

검색할 번호입력(1.의사 2.환자)  >>1
검색할 이름입력:kim
1, kim, 33, 중앙, 방사선
Comments