ArrayList란 무엇일까?

ArrayList에서 선언된 가장 중요한 함수를 통해 

개념을 이해해볼 것이다.



List - ArrayList

    - null 값을 저장할 수 있다.

    - 값을 중복 저장할 수 없다.

    - 값을 넣는 순서대로 저장한다.

      그래서 값을 꺼낼 때도 넣은 순서대로 꺼낼 수 있다.

    - 값을 꺼낼 때 숫자 인덱스를 사용하여 꺼낸다.



1)

ArraList 1. Object[] 배열 생성 코드를 작성한다.


public class ArrayList_ex1 {

 
  // Object 배열을 생성할 때, 기본적으로 생성해줘야 하는 사이즈(DEFAULT_SIZE)를 지정해준다.
  public static final int DEFAULT_SIZE = 10;
  // Object 배열에 값을 넣어줄 때, 추가로 생성해주고 싶은 사이즈(GROW_SIZE)를 지정해준다.
  public static final int GROW_SIZE = 3;
 
  Object[] list;
 
  // ArrayList_ex1 인스턴스를 생성하자마자, 호출되는 생성자 함수에서
  // 자동적으로 Object 배열의 빈 값을 10개 생성해주도록 한다.
  public ArrayList_ex1() {
   list = new Object[10];
  } 

}



2)

ArrayList 2. new ArrayList_ex1(숫자); 작성시 호출되는 

Object[] 배열 생성자 코드를 작성한다.


 // 기본 사이즈나 추가 사이즈보다 작은 수가 넘어오면 기본 사이즈로 배열을 생성한다.
public ArrayList_ex1(int capacity) {
 if (capacity < DEFAULT_SIZE || capacity < GROW_SIZE) {
   list = new Object[DEFAULT_SIZE];
 } else { // 그 외에는 입력받은 숫자대로 배열을 생성한다.
   list = new Object[capacity];
 }
}




3)

ArrayList 3. 배열의 길이를 증가시키는 increaseList() 

메서드 코드를 작성한다.


// 배열의 길이를 증가시키는 메서드. 내부 메서드이기 때문에 private을 사용한다
private void increaseList() {
  // 생성된 배열의 길이에 GROW_SIZE를 더 한 만큼 배열을 추가로 생성한다.
  Object[] newList = new Object[list.length + GROW_SIZE];
 
  // 반복문을 통해, 새롭게 생성되었던 newList 배열의 각 인덱스 값에 list 배열 값들을 저장한다.
  for (int i = 0; i < list.length; i++) {
   newList[i] = list[i];
  }
 
  // list 변수에 newList 배열의 주소를 할당해주면 된다.
  list = newList;

}




4)

ArrayList 4. 배열에 값을 넣어주는 add() 메서드를 추가한다.


// 배열에 값을 넣어주는 메서드
public void add(Object obj) {
  // add 메서드가 호출될 때마다 length 값을 하나씩 증가시키면서 obj 값을 list 배열에 삽입한다.
  list[length++] = obj;
 
  // length와 배열의 길이가 일치하면 배열의 길이를 증가시킨다.
  if (length == list.length) {
    increaseList();
  }

}




5)

ArrayList 5. 배열에 저장된 값을 꺼내는 get() 메서드를 추가한다.


// 배열에 저장된 값을 꺼내는 get() 메서드를 추가한다.
public Object get(int index) {
 
  // index 값이 배열의 길이보다 많거나 0보다 작다면 에러처리를 해준다.
  if (index < 0 || index >= length) {
    throw new RuntimeException("배열 인덱스의 범위를 벗어났습니다.");
  }
 
  // 그외에는 list 배열에서 해당 인덱스에 저장된 값을 리턴한다
  return list[index];

}




6)

ArrayList 6. 배열에서 특정 인덱스를 제거하는 remove() 메서드를 추가한다.


// 배열에서 특정 인덱스를 제거하는 remove() 메서드를 추가한다.
public void remove(int index) {
 
  //index 값이 배열의 길이보다 많거나 0보다 작다면 에러처리를 해준다.
  if (index < 0 || index >= length) {
    throw new RuntimeException("배열 인덱스의 범위를 벗어났습니다.");
  }
 
  // 입력받은 index 값부터 list 배열에 있는 값들을 하나씩 당겨서 저장한다.
  // (덮어씌어 지면서 기존 값이 지워지는 것)
  for (int i = index; i < list.length - 1; i ++) {
    list[i] = list[i+1];
  }
 
  // 배열의 길이를 하나 줄인다.
  length--;

}






7)

ArrayList 7. 배열에서 특정 인덱스에 값을 저장하는 set() 메서드를 추가한다.


// 배열에서 특정 인덱스에 값을 저장하는 set() 메서드를 추가한다.
public void set(int index, Object obj) {
 
  //index 값이 배열의 길이보다 많거나 0보다 작다면 에러처리를 해준다.
  if (index < 0 || index >= length) {
    throw new RuntimeException("배열 인덱스의 범위를 벗어났습니다.");
  }
 
  // list[index]에 값을 저장시킨다.
  list[index] = obj;

}





main() 메서드 예제


import java.sql.Date;
public class Test_ArrayList{
  public static void main(String[] args) {
   ArrayList_ex1 dateList = new ArrayList_ex1();
   
    dateList.add(Date.valueOf("2017-3-1"));
    dateList.add(Date.valueOf("2017-5-3"));
    dateList.add(Date.valueOf("2017-5-5"));
    dateList.add(Date.valueOf("2017-5-9"));
    dateList.add(Date.valueOf("2017-6-6"));
    for (int i = 0; i < dateList.length(); i++) {
      System.out.println(dateList.get(i));
    }
    System.out.println("-------------------------");   
   
    dateList.remove(3);
    dateList.set(1, Date.valueOf("2017-5-4"));
   
    for (int i = 0; i < dateList.length(); i++) {
      System.out.println(dateList.get(i));
    }
       
  }

}


- 실행 결과 : 

2017-03-01

2017-05-03

2017-05-05

2017-05-09

2017-06-06

-------------------------

2017-03-01

2017-05-04

2017-05-05

2017-06-06




블로그 이미지

필로그래머

,

[Java] 자바 컬렉션 클래스 - [Set] HashSet (java.util.Hashset)


컬렉션 클래스 : HashSet (java.util.HashSet)

 - 저장하려는 객체에 대해 hashCode()를 호출하여

   그 리턴 값을 가지고 저장할 위치를 계산한다.

 - null 값을 저장할 수 있다.

 - 값을 중복 저장할 수 없다.

   이유 -> '집합'이기 때문

 - 값을 넣을 때 인스턴스의 해시값을 기준으로 저장하기 때문에

   순서대로 저장되지 않는다.

   그래서 값을 꺼낼 때도 순서대로 꺼낼 수 없다.

 - 값을 꺼낼 때 숫자 인덱스로 꺼낼 수 없다.

 - 예) HashSet



Set 컬렉션에서 값을 꺼내는 방법


 1) 배열을 리턴 받는다. (입력 순서대로 리턴 받을 수 없다.)

     - toArray()


Object[] valueList = dateSet.toArray();


for (int i = 0; i < valueList.length; i++) {
  System.out.println(valueList[i]);

}


 2) 값을 꺼내주는 메서드를 이용한다.

     - iterator()


Iterator iterator = dateSet.iterator();
 
while (iterator.hasNext()) { // hasNext() -> 꺼낼 데이터가 있는가?
  System.out.println(iterator.next());

}






* 주의!
  HashSet 컬렉션에 값을 저장할 때,
  인스턴스의 주소가 영향을 끼치는 것이 아니라

  hashCode()의 리턴 값이 영향을 끼친다.



HashSet과 hashCode() 메서드 예제


public static void main(String[] args) {
    HashSet set = new HashSet();
    
    set.add(new String("홍길동"));
    set.add(new String("임꺽정"));
    set.add(new String("유관순"));
    set.add(new String("윤봉길"));
    set.add(new String("안중근"));
    set.add(new String("김구"));
    set.add(new String("김구"));
    /* "김구" 문자열인 경우엔 서로 다른 인스턴스 임에도 불구하고 중복되지 않는다.
     *  왜?
     *  => Set은 객체(의 주소)를 저장할 때 그 객체에 대해 hashCode() 메소드를 호출한 후
     *     그 리턴 값을 위치를 계산한다.
     *  => String 클래스는 같은 값을 갖는 경우 같은 hash value를 리턴하도록
     *     hashCode()를 오버라이딩 하였다.
     *     즉 위의 두 개의 "김구" String 객체는 비록 인스턴스는 다르지만
     *     값이 같기 때문에 hashCode()의 리턴값도 같다.
     *     그래서 위치를 계산한 값도 같다.
     *     위치 계산 값이 같아서 같은 값으로 간주하기 때문에 중복 저장되지 않는다.
     */
   
    // 증명! -> 값이 다 똑같이 출력된다.
    System.out.println(new String("김구").hashCode());
    System.out.println(new String("김구").hashCode());
    System.out.println(new String("김구").hashCode());
     
   
    /* 결론!
     * HashSet 컬렉션에 값을 저장할 때,
     * 인스턴스의 주소가 영향을 끼치는 것이 아니라
     * hashCode()의 리턴 값이 영향을 끼친다.
     */
   
    Iterator iterator = set.iterator();
    while (iterator.hasNext()) { // 꺼낼 데이터가 있는가?
      System.out.println(iterator.next());
    }
}


블로그 이미지

필로그래머

,