[#13] Java Generic & Collection

2025. 2. 12. 15:08·LG 유플러스 유레카 SW/Java

Generic

  • 성능 향상을 위한 제네릭
package generic;

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

public class Test3 {

	public static void main(String[] args) {
		List<A> list=new ArrayList<>();
        
		list.add(new A());
		list.add(new B());
	}

}

class A{}
class B extends A{}

class Biz{
	public static void service(List<A> list) {
		for(A o:list) {
        	// ...
		}
	}
}

Wildcard

  • 제네릭에서는 타입에 의한 상속 관계를 허용하지 않음, 겉으로만 보고 판단 !
    ➡️ Wildcard 사용하기
ex) A 클래스를 상속하고 있는 B 클래스에 대해, Biz 클래스의 service 메서드에 접근할 시 컴파일 에러 발생

1️⃣ List<A> 타입을 받아들이는 service 메서드

package generic;

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

public class Test3 {

	public static void main(String[] args) {
		List<A> list=new ArrayList<>();

		list.add(new A());
		list.add(new B());
		
		List<B> list2 = new ArrayList<>();
		list2.add(new B());
		
		Biz.service(list2); // 컴파일 에러 발생
	}

}

class A{}
class B extends A{}

class Biz{
	public static void service(List<A> list) {
		for(A o:list) {
			// ...
		}
	}
}

➡️ 해결: extends 와일드 카드 사용

package generic;

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

public class Test3 {

	public static void main(String[] args) {
		List<A> list=new ArrayList<>();

		list.add(new A());
		list.add(new B());
		
		List<B> list2=new ArrayList<>();
		list2.add(new B());
		
		Biz.service(list2);
	}

}

class A{}
class B extends A{}

class Biz{
	public static void service(List<? extends A> list) { // A 클래스를 상속하고 있는 하위 클래스를 받아들인다는 의미
		for(A o:list) {
			// ...
		}
	}
}

2️⃣ List<B> 타입을 받아들이는 service 메서드

package generic;

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

public class Test3 {

	public static void main(String[] args) {
		List<A> list = new ArrayList<>();

		list.add(new A());
		list.add(new B());
		
		List<B> list2 = new ArrayList<>();
		list2.add(new B());
		
		Biz.service(list); // 컴파일 에러
	}

}

class A{}
class B extends A{}

class Biz{
	public static void service(List<B> list) {
		for(B o:list) {
			// ...
		}
	}
}

➡️ 해결: super 와일드 카드 사용

package generic;

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

public class Test3 {

	public static void main(String[] args) {
		List<A> list = new ArrayList<>();
        
		list.add(new A());
		list.add(new B());
		
		List<B> list2 = new ArrayList<>();
		list2.add(new B());
		
		Biz.service(list);
	}

}

class A{}
class B extends A{}

class Biz{
	public static void service(List<? super B> list) { // B가 상속하는 상위 클래스를 받아들인다는 의미
		// B의 super가  꼭 A만이라는 보장이 안됨
        // 타입 체크, 캐스팅이 필요 -> 성능 저하
		}
	}
}

 

Method Generic

package generic;

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

public class Test3 {

	public static void main(String[] args) {
		List<A> list = new ArrayList<>();

		list.add(new A());
		list.add(new B());
		
		List<B> list2 = new ArrayList<>();
		list2.add(new B());
		
		Biz.service(list);
		Biz.service(1);
	}

}

class A{}
class B extends A{}

class Biz{
	public static <T> void service(T list) {

	}
}
  • 좀 더 정제된 Method Generic
package generic;

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

public class Test3 {

	public static void main(String[] args) {
		List<A> list = new ArrayList<>();

		list.add(new A());
		list.add(new B());
		
		List<B> list2 = new ArrayList<>();
		list2.add(new B());
		
		Biz.service(list);
		
	}

}

class A{}
class B extends A{}

class Biz{
	public static <T> void service(List<T> list) {
		for(T o:list) {
			// ...
		}
	}
}

 

Colloection

많은 수의 데이터를 그 사용 목적에 적합한 자료구조로 묶어 하나로 그룹화한 객체

1. List

  • 순서 유지 O

📍 ArrayList

  • 단방향 포인터 구조
package collections;

import java.util.ArrayList;
import java.util.Collections;

public class ArrayListTest {

	public static void main(String[] args) {
		ArrayList<Member> list = new ArrayList<>();
		
		Member m1 = new Member("김철수", 38);
		Member m2 = new Member("홍길동", 20);
		Member m3 = new Member("이영희", 45);

		list.add(m1);
		list.add(m2);
		list.add(m3); 
		
		System.out.println(list.size());
		System.out.println(list);
		
		Collections.sort(list);
		System.out.println(list);
		
	}

}

📍 LinkedList

  • 양방향 포인터 구조
package collections;

import java.util.Collections;
import java.util.LinkedList;

public class LinkedListTest {

	public static void main(String[] args) {
		LinkedList<Member> list = new LinkedList<>();
		
		Member m1 = new Member("김철수", 38);
		Member m2 = new Member("홍길동", 20);
		Member m3 = new Member("이영희", 45);

		list.add(m1);
		list.add(m2);
		list.add(m3); 
		
		System.out.println(list.size());
		System.out.println(list);
		
		Collections.sort(list);
		System.out.println(list);
		
	}

}

 

2. Set

  • 순서 유지 X
  • 중복 허용 X

📍 HashSet

package collections;

import java.util.*;
public class HashSetTest {

	public static void main(String[] args) {

		HashSet<Member> set = new HashSet<>();

		Member m1 = new Member("김철수", 38);
		Member m2 = new Member("홍길동", 20);
		Member m3 = new Member("이영희", 45);
		Member m4 = new Member("김철수", 38);

		set.add(m1);
		set.add(m2);
		set.add(m3);
		set.add(m4);

		System.out.println(set.size());
		System.out.println(set);
		
		// 정렬 시 ArrayList로
		List<Member> list=new ArrayList<>(set);
		Collections.sort(list);
		System.out.println(list);

	}

}

📍 TreeSet

  • 정렬 기능
package collections;

import java.util.TreeSet;

public class TreeSetTest {

	public static void main(String[] args) {
		// 아이템들이 들어가는 순간 정렬
		TreeSet<Member> set = new TreeSet<>();
		
		Member m1 = new Member("김철수", 38);
		Member m2 = new Member("홍길동", 20);
		Member m3 = new Member("이영희", 45);
		Member m4 = new Member("김철수", 38);

		set.add(m1);
		set.add(m2);
		set.add(m3); 
		set.add(m4); 
		
		System.out.println(set.size());
		System.out.println(set);
		
	}

}

 

3. Map

  • key, value 쌍으로 이루어짐
  • key 중복 허용 X
  • value 중복 허용 O
  • 순서 유지 X

📍 HashMap

package collections;

import java.util.*;
public class HashMapTest {

	public static void main(String[] args) {

		Map<String, Member> map = new HashMap<>();

		Member m1 = new Member("김철수", 38);
		Member m2 = new Member("홍길동", 20);
		Member m3 = new Member("이영희", 45);
		Member m4 = new Member("김철수", 10);

		map.put(m1.getName(), m1);
		map.put(m2.getName(), m2);
		map.put(m3.getName(), m3);
		map.put(m4.getName(), m4); // key가 같으면 덮어쓰기

		System.out.println(map.size());
		System.out.println(map);

	}

}

 


스터디 - Collection 실습

Q) 멤버 정보가 POST 요청으로 들어올 때 Collection을 활용하여 저장해보기

 

1) ArrayList 활용

  • add 메서드를 통해 리스트에 바로 넣어주기
  • 단, 중복 체크를 못함..!
package com.kse.shop.controller;

import java.util.ArrayList;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.kse.shop.dto.Member;

@RestController
public class MemberController {
	
	ArrayList<Member> members = new ArrayList<>();
	
	@PostMapping("insertMember")
	public void insertMember(@RequestBody Member member) {
		System.out.println(member);
        
		members.add(member);
		System.out.println(members);
	}
}

A2) HashMap 활용

  • key의 중복을 허용하지 않기 때문에 멤버의 email을 key로 설정하여 저장하기
  • put 메서드 사용
  • getEmail()로 이메일 가져오기
  • 문제는 같은 key 값이 들어오면 value 값이 덮어 씌어진다는 점... 어떻게 해결하면 좋을까?
package com.kse.shop.controller;

import java.util.HashMap;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.kse.shop.dto.Member;

@RestController
public class MemberController {
	
	HashMap<String, Member> members = new HashMap<>();
	
	@PostMapping("insertMember")
	public void insertMember(@RequestBody Member member) {
		System.out.println(member);

		members.put(member.getEmail(), member);
		System.out.println(members);
	}
}

 


📚 과제

이전에 만든 쇼핑몰 페이지에서 회원가입 form 정보 post 요청하기
  •  index.html
    • name, email, password, confirm password 입력받기
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>쇼핑몰 페이지</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
      rel="stylesheet"
    />
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
  </head>
  <body>
  
    <!-- ... 생략 -->

    <!-- 회원가입 모달 -->
    <div class="modal fade" id="signupModal" tabindex="-1">
      <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title">회원가입</h5>
            <button
              type="button"
              class="btn-close"
              data-bs-dismiss="modal"
            ></button>
          </div>
          <div class="modal-body">
            <form>
              <div class="mb-3">
                <label class="form-label">이름</label>
                <input id="name" type="text" class="form-control" />
              </div>
              <div class="mb-3">
                <label class="form-label">이메일</label>
                <input id="email" type="email" class="form-control" />
              </div>
              <div class="mb-3">
                <label class="form-label">비밀번호</label>
                <input id="pwd" type="password" class="form-control" />
              </div>
              <div class="mb-3">
                <label class="form-label">비밀번호 확인</label>
                <input id="confirmPwd" type="password" class="form-control" />
              </div>
              <button id="signupBtn" type="button" class="btn btn-success w-100">
                가입하기
              </button>
            </form>

          </div>
        </div>
      </div>
    </div>
    <script src="./js/index.js"></script>
  </body>
</html>
  • index.js
    • id 요소를 기준으로 값 가져와서 post 요청
const headers = { "Content-Type": "application/json"};

document.getElementById("signupBtn").addEventListener('click', () => {
	const name = document.getElementById("name").value;
	const email = document.getElementById("email").value;
	const pwd = document.getElementById("pwd").value;
	const confirmPwd = document.getElementById("confirmPwd").value;
	
	let data = { name, email, pwd, confirmPwd };
	
	data = JSON.stringify(data);
	console.log(data);
	
	fetch('insertMember', {
		method: 'POST',
		headers,
		body: data
	});
})

 

  • Member.java
    • name, email, pwd, confirmPwd 멤버 변수 생성
    • getter/setter, toString 메서드 활용
package com.kse.shop.dto;

public class Member {

	private String name, email, pwd, confirmPwd;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getConfirmPwd() {
		return confirmPwd;
	}

	public void setConfirmPwd(String confirmPwd) {
		this.confirmPwd = confirmPwd;
	}

	@Override
	public String toString() {
		return "Member [name=" + name + ", email=" + email + ", pwd=" + pwd + "]";
	}

	
	
}
  • MemberController.java
    • 중복 이메일 검사
    • 비밀번호 & 비밀번호 확인 비교
    • HashMap을 활용해 email을 key로 하여 멤버 저장
package com.kse.shop.controller;

import java.util.HashMap;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.kse.shop.dto.Member;

@RestController
public class MemberController {
	
	HashMap<String, Member> members = new HashMap<>();
	
	@PostMapping("insertMember")
	public void insertMember(@RequestBody Member member) {
		System.out.println(member);
		
		// 중복 이메일 검사
		if (members.containsKey(member.getEmail())) {
			System.out.println("이미 존재하는 이메일입니다: " + member.getEmail());
			return;
		}

		// 비밀번호와 비밀번호 확인 비교
		if (!member.getPwd().equals(member.getConfirmPwd())) {
			System.out.println("비밀번호가 일치하지 않습니다.");
			return;
		}

		// 회원 저장
		members.put(member.getEmail(), member);
		System.out.println(members);
	}
}
728x90
반응형

'LG 유플러스 유레카 SW > Java' 카테고리의 다른 글

[#14] Java 재귀 & 배열 & Exception  (0) 2025.02.13
[#12] Java 코드 성능 & 가독성 높이는 법  (0) 2025.02.11
[#11] Java 다형성 + Class 다이어그램 그려보기  (0) 2025.02.10
[#10] Java 들어가기 + 알고리즘 스터디  (0) 2025.02.07
[#9] Java 들어가기 전에..  (0) 2025.02.06
'LG 유플러스 유레카 SW/Java' 카테고리의 다른 글
  • [#14] Java 재귀 & 배열 & Exception
  • [#12] Java 코드 성능 & 가독성 높이는 법
  • [#11] Java 다형성 + Class 다이어그램 그려보기
  • [#10] Java 들어가기 + 알고리즘 스터디
nueos
nueos
  • nueos
    nueos 공부 기록
    nueos
  • 전체
    오늘
    어제
    • 분류 전체보기 (191)
      • 해커톤 (1)
      • 네이버 BoostCamp (6)
      • LG 유플러스 유레카 SW (3)
        • React (21)
        • TypeScript (2)
        • JavaScript (2)
        • HTML+CSS (5)
        • Spring (7)
        • Java (6)
        • SQL (2)
        • Algorithm (8)
        • CX (6)
        • Git (2)
        • 프로젝트 (2)
        • 스터디 (9)
        • 과제 (8)
        • 특강 (1)
      • React (3)
      • Next (0)
      • Javascript (2)
      • HTML (2)
      • CSS (9)
      • Algorithm (6)
      • Database (0)
      • OS (13)
      • C++ (24)
      • Python (1)
      • jQuery (1)
      • Django (1)
      • Git (1)
      • 개발 지식 (3)
      • 정보 보안 (22)
      • 포렌식 (1)
      • 암호 (2)
      • 기타 (4)
      • 패스트캠퍼스 FE 프로젝트십 (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    스택
    Queue
    Stack
    디지랩챌린지
    큐
    heap
    기술로바꾸는세상
    제주지역혁신플랫폼지능형서비스사업단
    제주해커톤
    exhaustive search
    완전 탐색
    힙
    디지털혁신
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
nueos
[#13] Java Generic & Collection
상단으로

티스토리툴바