본문 바로가기
java

[JAVA] static, generic, list 개념 알기

by CodeMango 2023. 2. 7.

 

 

Static(정적)

정적(static)은 고정된이란 의미를 가지고 있습니다. Static이라는 키워드를 사용하여 Static변수와 Static메소드를 만들 수 있는데 다른말로 정적필드와 정적 메소드라고도 하며 이 둘을 합쳐 정적 멤버라고 합니다. (클래스 멤버라고도 합니다.) 정적 필드와 정적 메소드는 객체(인스턴스)에 소속된 멤버가 아니라 클래스에 고정된 멤버입니다. 그렇기에 클래스 로더가 클래스를 로딩해서 메소드 메모리 영역에 적재할때 클래스별로 관리됩니다. 따라서 클래스의 로딩이 끝나는 즉시 바로 사용할 수 있습니다.

Static 키워드를 통해 생성된 정적멤버들은 Heap영역이 아닌 Static영역에 할당됩니다. Static 영역에 할당된 메모리는 모든 객체가 공유하여 하나의 멤버를 어디서든지 참조할 수 있는 장점을 가지지만 Garbage Collector의 관리 영역 밖에 존재하기에 Static영역에 있는 멤버들은 프로그램의 종료시까지 메모리가 할당된 채로 존재하게 됩니다. 그렇기에 Static을 너무 남발하게 되면 만들고자 하는 시스템 성능에 악영향을 줄 수 있습니다.

 

정적(Static) 멤버 선언

필드나 메소드를 생성 시 인스턴스로 생성할것인지 정적으로 생성할것인지에 대한 판단 기준은 공용으로 사용하느냐 아니냐로 내리면 됩니다.

그냥 생성한다면 자동으로 인스턴스로 생성되며 정적으로 생성하려면 필드와 메소드 선언 시 static이라는 키워들를 추가적으로 붙이면 됩니다. 

static int num = 0; //타입 필드 = 초기값
public static void static_method(){} //static 리턴 타입 메소드 {}

 

- 자바에서 지역변수로는 static 쓸 수 없다.

- C언어에서는 지역변수로 static 쓸 수 있다.

- 객체 생성 안 하고 접근할 수 있다.

- static 변수는 프로그램 시작과 끝을 같이 한다.( 프로그램 꺼야 삭제됨)

 

 

정적(Static) 메서드 사용 예시

- static 메서드는 객체 생성하지 않아도 호출 가능하다.

- static 메서드에서는 this와 super로 접근할 수 없다.

- 검사 용도로 많이 사용된다.

class Name{
    static void print() { //클래스 메소드
	System.out.println("내 이름은 홍길동입니다.");
    }

    void print2() { //인스턴스 메소드
	System.out.println("내 이름은 이순신입니다.");
    }
}

public class Static_ex {
	
    public static void main(String[] args) {
        Name.print(); //인스턴스를 생성하지 않아도 호출이 가능
    	
        Name name = new Name(); //인스턴스 생성
        name.print2(); //인스턴스를 생성하여야만 호출이 가능
    }
}

https://coding-factory.tistory.com/524 참조

 

Generic

만약에 우리가 어떤 자료구조를 만들어 배포하려고 한다.

그런데 number 을 int, string, double 로 사용하고 싶을때 String에 대한 클래스, Integer에 대한 클래스 등 하나하나 타입에 따라 만들 것인가? 그건 너무 비효율적이다.

이러한 문제를 해결하기 위해 우리는 제네릭이라는 것을 사용한다.

 

이렇듯 제네릭(Generic)은 클래스 내부에서 지정하는 것이 아닌 외부에서 사용자에 의해 지정되는 것을 의미한다. 한마디로 특정(Specific) 타입을 미리 지정해주는 것이 아닌 필요에 의해 지정할 수 있도록 하는 일반(Generic) 타입이라는 것이다.

 

generic 사용 이유

배열 안에는 뭐가 들어올지 모른다. int, string 등등이 있을 것이므로 generic을 준비해야 한다. 

 

 

Generic(제네릭)의 장점

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

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

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

 

 

보통 제네릭은 아래 표의 타입들이 많이 쓰인다.

타입 설명
<T> Type
<E> Element
<K> Key
<V> Value
<N> Number

물론 반드시 한 글자일 필요는 없다. 또한 설명과 반드시 일치해야 할 필요도 없다. 예로들어 <Ele>라고 해도 전혀 무방하다. 다만 대중적으로 통하는 통상적인 선언이 가장 편하기 때문에 위와같은 암묵적(?)인 규칙이 있을 뿐이다.

 

그럼 각 상황별 선언 및 생성 방법을 알아보자.

 

클래스 및 인터페이스 선언

//<T>에 Integer 대입
	Box<Integer> box = new Box<Integer>(100);
    	System.out.println(box.getTemp()+2);  // 102 반환
        
//<T>에 String 대입      
    Box<String> box = new Box<Integer>("Hello");  
    	System.out.println(box.getTemp());	// Hello 반환 


class Box <T>{		
	T temp;
    
    public Box(T temp) {
    	this.temp = temp;
    }
    
    public T getTemp() {
    	return temp;
    }
    
    public void setTemp(T temp) {
    	this.temp = temp;
    }

기본적으로 제네릭 타입의 클래스나 인터페이스의 경우 위와같이 선언한다.

T 타입은 해당 블럭 { ... } 안에서까지 유효하다.

 

 

또한 여기서 더 나아가 제네릭 타입을 두 개로 둘 수도 있다. 

//호출
BoxMap<Integer, String> boxmap = new BoxMap<Integer, String>(1001, "홍길동")


public BoxMap ( KEY, VALUE>{
	KEY key;
    VALUE value;
    
    public BoxMap(KEY key, VALUE value){
    	this.key = key;
        this.value = value;
}
}

https://st-lab.tistory.com/153 참조

 

 

list

참조 : https://codechacha.com/ko/java-generics/

배열은 미리 몇개의 자리를 마련해놓는다. 데이터 추가/삭제할 때 중간에 넣고 빼는 작업을 반복해야 한다. 데이터가 많을 때 이런 작업을 하기 어렵다. 이를 보강하기 위해 list가 나왔다.

 

List는 Object 형태로 저장하기 때문에 어떤 타입의 데이터가 저장되어있는지 알 수 없습니다. 그렇기 때문에 get()을 호출하면 Object가 리턴됩니다.

따라서, List에서 데이터를 가져올 때는 다음과 같이 형변환을 해줘야 합니다. 형변환을 하지 않으면 컴파일 에러가 발생합니다.

 

 

데이터 추가하기

//	ArrayList<Human> list = new ArrayList<Human>();
		List<Human> list = new ArrayList<Human>();
		
// list.add : 추가 -> 3명
		Human hman = new Human("홍길동", 24);
		list.add(hman);
		
		hman = new Human("성춘향", 16);
		list.add(hman);
		
		list.add(new Human("일지매", 22));
        
/* list의 길이는 list.size()라고 쓴다.
		for (int i = 0; i < list.size(); i++) {
			Human h = list.get(i);
			System.out.println(h.toString());
		}*/
		
		for(Human h : list) {
			System.out.println(h.toString());
		}
		System.out.println();  // 개행
		
		hman = new Human("홍두께", 23);
		list.add(1, hman);

데이터 삭제하기

// list.remove : 삭제 -> 1명
		String name = "일지매";
		
		int findindex = -1; //index -1을 찾을거임
		for (int i = 0; i < list.size(); i++) {
			Human h = list.get(i); // get으로 꺼낸다
			if(name.equals(h.getName())) { // 꺼낸값이 일지매와 같다면
				findindex = i;  // 그 인덱스값 반환한다.
				break;
			}
		}
		list.remove(findindex); //그 인덱스값을 삭제한다.

 

데이타 수정하기

// list.set : 수정 -> 1명
		Human updateHman = new Human("이몽룡", 17); //바꿀 데이타 준비
		list.set(1, updateHman);

6교시 list 24분까지 들었음

 

 

 

 

sample37 원본파일 

human.java

    package sample37;

public class Human {
	String name;
	int age;
	
	public Human() {
	}
	public Human(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "Human [name=" + name + ", age=" + age + "]";
	}
}

MainClass.java

package sample37;

import java.util.ArrayList;
import java.util.List;

public class MainClass {
	public static void main(String[] args) {
		/*
			Collection : 수집(데이터, Object)
			
			List : 목록
			 	ArrayList
			 		배열처럼 사용할 수 있는 리스트 == 유동적배열
			 		선형구조
			 		배열처럼 index로 접근하고 관리한다.	0 1 2 3 4	
			 		검색속도가 빠르다
			 	
			 	LinkedList		
			 		추가/삭제 속도 빠르다
			
			Map : 사전
				HashMap				
				TreeMap
		*/
		
	//	ArrayList<Integer> arrlist = new ArrayList<Integer>(); 
		ArrayList<String> arrlist = new ArrayList<String>();
		
		// 추가
		String str = new String("Tigers");
		arrlist.add(str);
		
		arrlist.add("Eagles");
		arrlist.add("Bears");
		
		// 리스트의 크기(길이)
		System.out.println(arrlist.size());
		
		for(int i = 0;i < arrlist.size(); i++) {
			System.out.println(i + ":" + arrlist.get(i));    // == arrlist[i]
		}
		System.out.println();
		
		
		arrlist.add("Lions");  // 맨뒤에 추가	
		
		for(int i = 0;i < arrlist.size(); i++) {
			System.out.println(i + ":" + arrlist.get(i));    // == arrlist[i]
		}
		System.out.println();
		
		
		arrlist.add(2, "Giants");
		
		for(int i = 0;i < arrlist.size(); i++) {
			System.out.println(i + ":" + arrlist.get(i));    // == arrlist[i]
		}
		System.out.println();
		
		// 삭제
		arrlist.remove(1);	// 삭제하고 싶은 index
		
		for(int i = 0;i < arrlist.size(); i++) {
			System.out.println(i + ":" + arrlist.get(i));    // == arrlist[i]
		}
		System.out.println();
		
		// 검색
		int index = arrlist.indexOf("Giants");
		System.out.println("데이터가 있습니다 " + index);
		
		for(int i = 0;i < arrlist.size(); i++) {
			String s = arrlist.get(i);
			if("Giants".equals(s)) {
				index = i;
				break;
			}			
		}
		
		System.out.println("데이터가 있습니다 " + index);
		System.out.println();
		
		// 수정
		String updateStr = "Twins";
		
		arrlist.set(2, updateStr);
		for(int i = 0;i < arrlist.size(); i++) {
			System.out.println(i + ":" + arrlist.get(i));    // == arrlist[i]
		}
		System.out.println();
		
		
		
	//	ArrayList<Human> list = new ArrayList<Human>();
		List<Human> list = new ArrayList<Human>();
		
// list.add : 추가 -> 3명
		Human hman = new Human("홍길동", 24);
		list.add(hman);
		
		hman = new Human("성춘향", 16);
		list.add(hman);
		
		list.add(new Human("일지매", 22));
		/*
		for (int i = 0; i < list.size(); i++) {
			Human h = list.get(i);
			System.out.println(h.toString());
		}*/
		
		for(Human h : list) {
			System.out.println(h.toString());
		}
		System.out.println();
		
		hman = new Human("홍두께", 23);
		list.add(1, hman);
		
		for(Human h : list) {
			System.out.println(h.toString());
		}
		System.out.println();
				
// list.remove : 삭제 -> 1명
		String name = "일지매";
		
		int findindex = -1;
		for (int i = 0; i < list.size(); i++) {
			Human h = list.get(i);
			if(name.equals(h.getName())) {
				findindex = i;
				break;
			}
		}
		list.remove(findindex);
		
		for(Human h : list) {
			System.out.println(h.toString());
		}
		System.out.println();
		
		// 검색 -> 이름
		name = "성춘향";		
		findindex = -1;
		for (int i = 0; i < list.size(); i++) {
			Human h = list.get(i);
			if(name.equals(h.getName())) {
				findindex = i;
				break;
			}
		}
		if(findindex != -1) {
			System.out.println(list.get(findindex).toString());
		}else {
			System.out.println("데이터가 없습니다");
		}
		System.out.println();
				
// list.set : 수정 -> 1명
		Human updateHman = new Human("이몽룡", 17); //바꿀 데이타 준비
		list.set(1, updateHman);
		
		for(Human h : list) {
			System.out.println(h.toString());
		}
				
		System.out.println();
		
		System.out.println(list.toString());
		// Arrays.toString()
	}
}

댓글