본문 바로가기
Project/SpringBoot

인게임 유저 관리 ( 중복 계정, equals()와 hashcode() 오버라이드 )

by 꽃요미 2025. 1. 5.

Intro

* 동일 계정으로 동일 방에 여러번 입장을 하면 입장이 안되어야 하는게 정상이다.

그래서 Set<> 자료구조를 사용하여 동일한 유저들은 중복해서 추가를 막는 방식으로 생각하였다.

* 하지만 같은 UserID, RoodID를 가짐에도 동일 객체로 인식하지 않는 문제가 발생하였다.

* 객체의 값으로 동일성을 비교하려면 클래스 안에 equals() 함수와 hashcode() 함수를 @Override 하여 동등성을 보장해야한다.

 

아래는 코드 문제점이다.

 

Set<InGameUser> inGameUserSet = game.getGameUser();

// 동일 사용자지만 다른 인스턴스라 중복 허용
InGameUser user1 = new InGameUser(1L, 100L, "Alice", "USER", false);
InGameUser user2 = new InGameUser(1L, 100L, "Alice", "USER", false);

inGameUserSet.add(user1); // 성공
inGameUserSet.add(user2); // 중복이 아님, add 허용

 

* 객체 user1과 user2가 존재하는데, 두개의 객체의 값은 동일하다.

* 하지만 Set<> 자료구조는 두개의 객체를 다른 객체로 인식하고 있기 때문에 .add() 메서드 호출을 성공시킨다.

 

* 해결 방법 : equals()와 hashCode() 오버라이드

- InGameUser 클래스에 equals()와 hashCode() 추가

 Java 16에서 record를 사용하면.

   1. record는 자동으로 equals()와 hashCode()를 생성해주므로, 별도 @Override가 필요 없다.

   2. 기존 InGameUser가 record가 아니라면, 클래스로 변경하거나 수동으로 오버라이드 해야 한다.

 

import java.util.Objects;

public class InGameUser {
    private final Long roomId;
    private final Long id;
    private final String username;
    private final String role;
    private boolean readyStatus;

    // 생성자, getters, setters...

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        
        InGameUser that = (InGameUser) o;
        return Objects.equals(roomId, that.roomId) &&
               Objects.equals(id, that.id) &&
               Objects.equals(username, that.username) &&
               Objects.equals(role, that.role);
    }

    @Override
    public int hashCode() {
        return Objects.hash(roomId, id, username, role);
    }
}

 

- equals 함수의 마지막 return 문에 4가지의 값이 동등한지 확인하고 있다.

'Project > SpringBoot' 카테고리의 다른 글

NginX를 적용한 로드밸런싱 적용  (0) 2025.01.31
AWS 프로젝트 배포과정  (0) 2025.01.31
깃허브 액션에 대해서  (0) 2025.01.30
DDL ( Data Definiton Language ) 작업  (0) 2024.12.21