728x90
ArrsyList

 

List 인터페이스의 구현체


ArrayList의 객체를 추가하면 객체가 인덱스로 관리된다.


일반 배열은 크기가 고정이라 크기 변경이 불가하지만, ArrayList는 크기 변경이 가능하다.

(저장용량을 초과한 객체가 들어오면 자동으로 저장용량을 늘린다)

 

import 필요

ArrayList 선언방법

1. ArrayList<자료형> 객체명 = new ArrayList<자료형>( );

ArrayList<Integer> al = new ArrayList<Integer>();

 

2. ArrayList<자료형> 객체명 = new ArrayList<자료형>(다른 ArrayList)

ArrayList<String> al01 = new ArrayList<String>();
al01.add("홍길동");
al01.add("김길동");
al01.add("이길동");
al01.add("박길동");
al01.add("최길동");
		
System.out.println(al01);				
		
ArrayList<String> al02 = new ArrayList<String>(al01);	//al02소스로 al01이 와도 값만 가져간다.
System.out.println(al02);				
		
System.out.println(al01 == al02);			//값만 가져왔기 때문에 두 객체는 다른 객체.

al02.add("황길동");
System.out.println(al02);

[실행결과]

[홍길동, 김길동, 이길동, 박길동, 최길동]
[홍길동, 김길동, 이길동, 박길동, 최길동]
false
[홍길동, 김길동, 이길동, 박길동, 최길동, 황길동]

값 추가하기

.add(입력값)

index 0부터 차례대로 값이 추가됨

 

ArrayList<Integer> al = new ArrayList<Integer>();

System.out.println(al);

al.add(10);	//index 0
al.add(20);	//1
al.add(30);	//2
al.add(40);	//3
al.add(50);	//4

System.out.println(al);

[실행결과]

[]
[10, 20, 30, 40, 50]

값 호출하기

.get(인덱스)

해당 인덱스값 호출

Integer int1 = al.get(0);
Integer int2 = al.get(3);

System.out.println(int1);
System.out.println(int2);

[실행결과]

10

40

 

특정 인덱스 삭제

.remove(인덱스)

해당 인덱스값 삭제

al.remove(0);

System.out.println(al);

[실행결과]

[20, 30, 40, 50]

특정 인덱스에 값 추가

.add(인덱스, 값)

al.add(0, 1000);

System.out.println(al);

[실행결과]

[1000, 20, 30, 40, 50]

특정 인덱스 수정

.set(인덱스, 수정할 값)

 

al.set(al.size() - 1, 5000);	//al의 크기 -1 (제일 끝자리 인덱스)

System.out.println(al);

[실행결과]

[1000, 20, 30, 40, 5000]

특정 값이 있는지 찾기

.contains(찾는 값)

  • 있다면 true
  • 없다면 false
System.out.println(al.contains(30));
System.out.println(al.contains(60));

[실행결과]

true

false

특정 값의 인덱스 반환

.indexOf(반환할 값)

  • 있다면 해당값의 인덱스
  • 없다면 -1
System.out.println(al.indexOf(30));
System.out.println(al.indexOf(60));

[실행결과]

2

-1

해당 배열에 값이 비어있는지 확인

.isEmpty( );

  • 비어있다면 true
  • 비어있지 않다면 false
System.out.println(al.isEmpty());

[실행결과]

false

전체 코드

ArrayList<Integer> al = new ArrayList<Integer>();	//ArrayList 선언

System.out.println(al);

al.add(10);						//값 추가
al.add(20);
al.add(30);	
al.add(40);
al.add(50);	
System.out.println(al);

Integer int1 = al.get(0);				//값 호출
Integer int2 = al.get(3);

System.out.println(int1);
System.out.println(int2);

al.remove(0);						//특정 인덱스 삭제
System.out.println(al);

al.add(0, 1000);					//특정 인덱스에 값 추가
System.out.println(al);

al.set(al.size() - 1, 5000);				//특정 인덱스 수정
System.out.println(al);

System.out.println(al.contains(30));			//특정 값이 있는지 찾기
System.out.println(al.contains(60));

System.out.println(al.indexOf(30));			//특정 값의 인덱스 반환
System.out.println(al.indexOf(60));

System.out.println(al.isEmpty());			//해당 배열에 값이 비어있는지 확인

예제 1.

<랜덤값 지정하기>

  • 1 ~ 100 까지의 수 중 10가지의 랜덤한 수 를 리스트에 넣기
  • Collections import하여 사용
ArrayList<Integer> al = new ArrayList<Integer>();
    
for (int i = 0; i < 10; i++) {
	al.add((int)(Math.random() * 100 + 1));
}
System.out.println(al);

Collections.sort(al);
System.out.println(al);

Collections.shuffle(al);
System.out.println(al);
  • Collections.sort(객체명) : 오름차순 정렬 
  • Collections.shuffle(객체명) : 무작위 정렬 

[3회 실행결과]

[95, 71, 32, 19, 68, 82, 46, 33, 70, 96]
[19, 32, 33, 46, 68, 70, 71, 82, 95, 96]
[68, 46, 82, 70, 95, 96, 33, 71, 19, 32]

 

[94, 95, 56, 9, 26, 64, 76, 37, 74, 2]
[2, 9, 26, 37, 56, 64, 74, 76, 94, 95]
[95, 76, 74, 2, 64, 56, 26, 37, 94, 9]

 

[39, 93, 12, 32, 23, 51, 59, 21, 25, 17]
[12, 17, 21, 23, 25, 32, 39, 51, 59, 93]
[12, 21, 59, 93, 32, 23, 17, 51, 25, 39]

예제 2.

<ArrayList 안에 ArrayList 넣기>

  • [1, 2, 3]
    [4, 5, 6]
    [7, 8, 9] 의 형태로 출력
ArrayList<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
ArrayList<String> innerList = new ArrayList<String>();
innerList.add("1");
innerList.add("2");
innerList.add("3");
list.add(innerList);
		
innerList = new ArrayList<String>();
innerList.add("4");
innerList.add("5");
innerList.add("6");
list.add(innerList);
		
innerList = new ArrayList<String>();
innerList.add("7");
innerList.add("8");
innerList.add("9");
list.add(innerList);
		
for (ArrayList<String> in: list) {
	System.out.println(in);
}

[실행결과]

[1, 2, 3]
[4, 5, 6]
[7, 8, 9]

'JAVA' 카테고리의 다른 글

HashSet  (0) 2021.07.22
LinkedList  (0) 2021.07.22
컬렉션 (Collection)  (0) 2021.07.20
제네릭 (Generic)  (0) 2021.07.20
랩퍼 (Wrapper)  (0) 2021.07.19
728x90
Collection : 데이터의 집합, 그룹

 

같은 타입의 참조값을 여러개 저장하기 위한 데이터의 집합, 그룹을 의미한다.

 

자바 컬렉션 프레임워크(JCF)는 이러한 자료구조인 컬렉션과 이를 구현하는 클래스를 정의하는 인터페이스를 제공한다.

 

<자바 컬렉션 프레임워크의 상속 구조>


Collection 인터페이스의 종류와 특징

 

  키 중복 허용 값 중복 허용 순서 유지
List O O O
Set X X O
Map X O X

1. List

순서가 있는 데이터의 집합

 

데이터의 중복을 허용한다.

 

  • LinkedList
    양방향 포인터 구조로 데이터의 삽입, 삭제가 빈번할 경우 데이터의 위치정보만 수정하면 되기에 유용
    스택, 큐, 양방향 큐 등을 만들기 위한 용도로 쓰임

  • Vector
    과거에 대용량 처리를 위해 사용했으며, 내부에서 자동으로 동기화처리가 일어나 비교적 성능이 좋지 않고 무거워 잘 쓰이지 않음

  • ArrayList
    단방향 포인터 구조로 각 데이터에 대한 인덱스를 가지고 있어서 조회 기능에 성능이 뛰어남

2. Set

순서를 유지하지 않는 데이터의 집합

 

데이터의 중복을 허용하지 않는다.

 

  • HashSet
    가장빠른 임의 접근 속도
    순서를 예측할 수 없음

  • TreeSet
    정렬방법을 지정할 수 있음

3. Map

키(key), 값(value)의 쌍으로 이루어진 데이터의 집합

 

순서는 유지되지 않으며, 키의 중복은 허용하지 않으나 값의 중복은 허용한다.

 

  • HashMap
    중복과 순서가 허용되지 않음
    null값 가능


  • HashTable
    HashMap보다는 느리지만 동기화 지원
    null값 불가능

  • TreeMap
    정렬된 순서대로 키와 값을 저장하여 검색이 빠름

'JAVA' 카테고리의 다른 글

LinkedList  (0) 2021.07.22
ArrayList  (0) 2021.07.22
제네릭 (Generic)  (0) 2021.07.20
랩퍼 (Wrapper)  (0) 2021.07.19
메모리 (Memory)  (0) 2021.07.19
728x90
Generic 

 

데이터 형식에 의존하지 않고 하나의 값이 여러 다른 데이터 타입들을 가질 수 있도록 하는 방법으로,

클래스 내부에서 지정하는 것이 아닌 외부에서 사용자에 의해 지정된다.

 

ex)

객체<타입> 객체이름 = new 객체<타입>();

 

<주로 사용되는 타입>

타입 설명
<T> Type (데이터 타입)
<E> Element (요소)
<K> Key (키)
<V> Value (값)
<N> Number (숫자)

※ 타입이 설명과 반드시 일치해야 할 필요는 없지만 일반적으로 사용되는 선언이 보기에 편하다.


Generic의 장점

 

  1. 제네릭을 사용하면 잘못된 타입이 들어올 수 있는 것을 컴파일 단계에서 방지할 수 있다.
    =안정성이 높아진다.

  2. 클래스 외부에서 타입을 지정 해주기 때문에 따로 타입을 체크하고 변환해줄 필요가 없다.
    =관리하기가 편하다.

  3. 비슷한 기능을 지원하는 경우 코드의 재사용성이 높아진다.

Generic 사용방법

1. 클래스 및 인터페이스 선언

타입 파라미터로 명시할 수 있는 것은 참조타입(R타입)만 사용할 수 있다.

(int, double, char... 등의 기본타입(P타입)은 사용할 수 없다.)

때문에 기본타입의 경우 Integer, Double, Character... 등의 랩퍼클래스로 사용된다.

public class ClassName <T, K> { ... }
//기본적으로 제네릭타입의 클래스나 인터페이스의 경우 위와같이 선언한다.
//선언된 <T, K>의 범위는 { ... } 까지이다.

public class Main {
	public static void main(String[] args) {
    	ClassName<String, Integer> a = new ClassName<String, Integer>();
        //a객체의 ClassName의 T는 String, K는 Integer가 된다.
    }
}

2. 제네릭 클래스

외부 클래스에서 제네릭 클래스를 생성할 때 괄호< > 안의 타입을 파라미터로 보내 제네릭 타입을 지정해 준다.

class ClassName<E> {	 		//제네릭 클래스
	
	private E element;		//제네릭 타입 변수 element
	
	void set(E element) {		//제네릭 파라미터 메소드
		this.element = element;
	}
	
	E get() {			//제네릭 타입 반환 메소드
		return element;
	}
}
 
public class Generic {
	public static void main(String[] args) {
		
		ClassName<String> a = new ClassName<String>();
		//a객체의 ClassName의 E제네릭타입은 String으로 모두 변환된다
        
		ClassName<Integer> b = new ClassName<Integer>();
		//b객체의 ClassName의 E제네릭타입은 Integer로 모두 변환된다
        
		a.set("10");
		b.set(10);
	
		System.out.println("a data : " + a.get());
		System.out.println("a E Type : " + a.get().getClass().getName());	
		//반환된 변수의 타입 출력 
            
		System.out.println();
        
		System.out.println("b data : " + b.get());
		System.out.println("b E Type : " + b.get().getClass().getName());
		//반환된 변수의 타입 출력 		
	}
}
  • getClass( ).getName( ) : 현재 실행중인 클래스의 클래스명 출력

[실행결과]

a data : 10
a E Type : java.lang.String

b data : 10
b E Type : java.lang.Integer

3. 제네릭 메소드

매개변수 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드

정적 메소드로 선언할 때 사용된다.

 

클래스에서와는 다르게 반환타입 이전에 제네릭 타입< >을 선언한다.

타입 파라미터를 리턴 타입과 매개변수에 사용한다.

 

 

※ 클래스는 인스턴스 앞에 있는 데이터형을 보고 제네릭 타입을 결정하고,

     메소드는 뒤에 있는 매개값을 보고 제네릭 타입을 결정한다.

 

ex)

제네릭 메소드 선언

public <T> T genericMethod(T t) {
		...
}
  • 접근제어자 <제네릭타입> 리턴타입 메소드명( 제네릭타입 파라미터 ) {
    }

제네릭 메소드 호출

T<Integer> T = genericMethod(100);		
//매개값이 100이기 때문에 타입 파라미터를 Integer로 추정

T<Integer> T = <Integer> genericMethod(100);	
//제네릭타입을 Integer로 지정했기 때문에 타입 파라미터를 Integer로 지정
  • 리턴타입 변수 = 메소드명(매개값);
  • 리턴타입 변수 = <구체적타입> 메소드명(매개값);

제네릭 클래스에서 사용한 예제에 제네릭 메소드 추가

  •  

[실행결과]

a data : 10
a E Type : java.lang.String

b data : 10
b E Type : java.lang.Integer

<T> returnType : java.lang.Integer
<T> returnType : java.lang.String
<T> returnType : ClassName


와일드 카드 <?>

 

  • <? extends a> : 상한 제한 (Upper bound)
    a와 a의 자식 타입만 사용 가능
    특정 타입만 제한하고 싶을 경우 사용한다.

  • <? super a> : 하한 제한 (Lower bound)
    a와 a의 부모 타입만 사용 가능
    해당 객체가 업캐스팅(Up Casting)이 될 필요가 있을 때 사용한다.

  • <?> : 제한 없음 (Un bound)
    모든 타입의 객체 사용 가능
    데이터가 아닌 기능의 사용에만 관심이 있는 경우 (어떤 타입으로 리턴받아도 상관 없을 경우) 사용한다.

※ <b extends a>와 <? extends a>는 비슷한 구조지만 차이점이 있다.

  • <b extends a>
    a와 이를 상속하는 Integer, Short, Double... 등의 타입이 지정될 수 있으며, 객체 혹은 매소드를 호출할 경우
    b는 지정된 타입으로 변환이 된다.

  • <? extends a>
    a와 이를 상속하는 Integer, Short, Double... 등의 타입이 지정될 수 있지만, 객체 혹은 메소드를 호출할 경우
    지정되는 타입이 없어 타입 참조를 할 수 없다.

 

다음 그림과 같이 서로 다른 클래스들이 상속관계를 갖고 있다고 가정했을 경우

 

extends

<T extends B>	// B와 C타입만 올 수 있음
<T extends E>	// E타입만 올 수 있음
<T extends A>	// A, B, C, D, E 타입이 올 수 있음
 
<? extends B>	// B와 C타입만 올 수 있음
<? extends E>	// E타입만 올 수 있음
<? extends A>	// A, B, C, D, E 타입이 올 수 있음
  • 뒤에 오는 타입이 최상위 타입으로 한계가 정해진다.

super

<K super B>	// B와 A타입만 올 수 있음
<K super E>	// E, D, A타입만 올 수 있음
<K super A>	// A타입만 올 수 있음
 
<? super B>	// B와 A타입만 올 수 있음
<? super E>	// E, D, A타입만 올 수 있음
<? super A>	// A타입만 올 수 있음
  • 뒤에 오는 타입이 최하위 타입으로 한계가 정해진다

<?>

<?> //A, B, C, D, E 타입이 올 수 있음
  • <? extends Object>와 동일하다

'JAVA' 카테고리의 다른 글

ArrayList  (0) 2021.07.22
컬렉션 (Collection)  (0) 2021.07.20
랩퍼 (Wrapper)  (0) 2021.07.19
메모리 (Memory)  (0) 2021.07.19
Enum  (0) 2021.07.19
728x90
Wrapper Class

 

자료형은 크게 기본형(P타입)과 참조형(R타입)으로 나뉜다.

컬랙션에 값을 담을 때 R타입만 담을 수 있고, P타입은 컬랙션에 담을 수 없기 때문에 
P타입 자료형을 R타입 자료형으로 만들어 주는 것을 랩퍼 클래스 라고 한다. 

 

기본 자료형의 값을 멤버 변수의 값으로 저장하고
이 값 주위로 값을 가공하는 메소드 들이 감싸고 있다고 해서 랩퍼(wrapper : 감싸다) 클래스라고 불린다.

 

기본 자료형의 값을 컬랙션에 담기 위해서 랩퍼 클래스를 사용한다.

 

모든 기본 자료형은 그에 대응하는 랩퍼 클래스가 있다.

기본 자료형 (P타입) 랩퍼 클래스
byte Byte
short Short
int ※ Integer
long Long
float Float
double Double
char ※ Character
boolean Boolean

예제 1.

<랩퍼클래스에 값 저장하기>

  • String str = new String("값"); 과 유사한 형식으로 가능하다
Integer integer = new Integer(10);
Integer integer2 = 10;
//Integer integer3 = "10"; ---- 오류 발생

System.out.println(integer); 
System.out.println(integer2);

[실행결과]

10

10

예제 2.

<R타입에서 P타입으로 변환하기>

  • Value( )로 캐스팅 없이 변환 가능

integer to int

int numInt2 = integer2.intValue();

 

integer to short

short numShort = integer.shortValue();

예제 3.

<랩퍼클래스의 MIN_VALUE, MAX_VALUE>

System.out.println(Integer.MIN_VALUE); 
System.out.println(Integer.MAX_VALUE);

[실행결과]

-2147483648

2147483647

예제 4.

<랩퍼클래스의 진법 변환>

 

10진법 to n진법

System.out.println(Integer.toBinaryString(3));	//2진수
System.out.println(Integer.toOctalString(9));	//8진수
System.out.println(Integer.toHexString(17));	//16진수

[실행결과]

11

11

11

 

n진법 to 10진법

String b = Integer.toBinaryString(3); 
String o = Integer.toOctalString(9); 
String h = Integer.toHexString(17); 

System.out.println(Integer.parseInt(b, 2)); 
System.out.println(Integer.parseInt(o, 8)); 
System.out.println(Integer.parseInt(h, 16));

[실행결과]

9

17


※ n진법 숫자 표현

 

2진법 0b__

int bi = 0b11; //2+1 = 3

 

8진법 0__

int oi = 011; //8+1 = 9

 

16진법 0x__

int hi = 0x11; //16+1 = 17

 

※※ n진법으로 값을 저장해도 십진법으로 반환된다.

int bi = 0b11;
int oi = 011; 
int hi = 0x11; 
		
System.out.println(bi); 
System.out.println(oi);
System.out.println(hi);

 

[실행결과]

3

9

17


예제 5.

<Integer - Integer 값 비교하기>

  • == : 같은 객체이면 true, 아니면 false
  • .equals( ) : 같은 값을 가지면 true, 아니면 false
  • a.compareTo(b) : 
    a == b : 0
    a > b : +1
    a < b : -1
integer = 200;						//integer : Integer타입 200
integer2 = new Integer(200);				//integer2 : Integer타입 200

System.out.println(integer == integer2);		//같은 객체가 아니기 때문에 false
System.out.println(integer.equals(integer2));		//같은 값이기 때문에 true
System.out.println(integer.compareTo(integer2));	//같은 값이기 때문에 0

[실행결과]

false

true

0

예제 6.

<int - Integer 값 비교하기>

numInt = 200;		//int
integer = 200;		//Integer

if(integer.equals(numInt)) {
//.equlals는 입력 값이 Integer여야 하기 때문에 
//컴파일러가 자동으로 numInt를 new Integer(numInt)로 변경하여 연산
System.out.println("같아요.");
}else {
System.out.println("달라요.");
}

[실행결과]

같아요.

예제 7.

<오토 박싱과 오토 언박싱>

 

오토 박싱 R = P

Integer integer = 200;
int numInt = 200;

integer = numInt;

 

오토 언박싱 P = R

int numInt = 200;
Integer integer = 200;

numInt = integer;
  • integer 객체 안의 int값이 나와서 numInt에 대입된다.

예제 8.

<HashSet에 넣기>

double pi = 3.14;
Double rPi = pi;	//R타입으로 변경
rPi = 3.14;

Set<Double> cSET = new HashSet<Double>();
cSET.add(rPI);	//R
cSET.add(3.14);	//p

예제 9.

<ArrayList에 넣기>

ArrayList<Integer> aar = new ArrayList<Integer>();
aar.add(integer);	//R
aar.add(integer2 + 10);	//R
aar.add(123);		//p

예제 10.

<Object 객체 연산>

  • Object를 이용하여 다양한 방법으로 계산하기
  • Object obj = 10
Object obj = 10;

int num = (int)obj + 1;
System.out.println(num);

[실행결과]

11

 

Object obj = 10;
obj = "10";					//obj의 자료형은 'Object'이고, 'String'이 아니다.

System.out.println(obj);

int num = Integer.valueOf((String)obj) + 1;	//Object -> String으로 캐스팅
System.out.println(num5);

[실행결과]

10

11

 

Object obj = 10;

int num = ((Integer)obj).intValue() + 1;
System.out.println(num);

[실행결과]

11

'JAVA' 카테고리의 다른 글

컬렉션 (Collection)  (0) 2021.07.20
제네릭 (Generic)  (0) 2021.07.20
메모리 (Memory)  (0) 2021.07.19
Enum  (0) 2021.07.19
다형성 (Polymorphism)  (0) 2021.07.19

+ Recent posts