Just Do IT!

[Java] TreeSet에서 custom 객체를 생성 후 ClassCastException 오류 본문

개발 공부/Java

[Java] TreeSet에서 custom 객체를 생성 후 ClassCastException 오류

MOON달 2024. 7. 24. 09:36
728x90
반응형

강의에서 과제가 주어져서 과제를 구현하다가, TreeSet 관련해서 오류가 생겨서 해결한 기록을 작성하려 한다.

비록 chatGPT와 여러 블로그들을 참고했지만, 그래도 무엇이 원인이고 해결 방법이 무엇인지 알게 되었으니까.

 

 

우선, 간단하게 과제는

Book 클래스 / BookManager 클래스 / BookCompartor / BookExample로 구성되어 있다.

 

BookManager 안에는 다양한 메소드들이 있는데, 그 중 TreeMap을 생성하여 Books의 book들을 모두 트리맵 형식으로 반환해야 하는 과제가 있었다. 전체 코드를 작성하자면,

package com.assignment;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;

public class BookManager {
	private List<Book> books;

	public BookManager() {
		this.setBooks(new ArrayList<Book>());
	}

	// void addBook(Book book)
	// books에 book 추가
	public void addBook(Book book) {
		getBooks().add(book);
	}

	// void removeBook(Book book)
	// books에 book 제거
	public void removeBook(Book book) {
		getBooks().remove(book);
	}

	// void sortBooksBy(Comparator<Book> comparator)
	// 해당 comparator에 따라 정렬
	public void sortBooksBy(Comparator<Book> comparator) {
		// List 컬렉션의 sort라는 메소드
		// sort(Comparator 인터페이스) -> 인터페이스의 추상 메소드를 재정의한 메소드가 동작되어 정렬
		getBooks().sort(comparator);
	}

	// Stack<Book> getStack()
	// 스택을 생성하여, Books의 book들을 모두 스택에 넣고 반환
	public Stack<Book> getStack() {
		Stack<Book> stack = new Stack<>();
		for (Book book : getBooks()) {
			stack.push(book);
		}
		return stack;
	}

	// Queue<Book> getQueue()
	// 큐를 생성하여, Books의 book들을 모두 큐에 넣고 반환
	public Queue<Book> getQueue() {
		Queue<Book> queue = new LinkedList<>();
		for (Book book : getBooks()) {
			queue.offer(book);
		}
		return queue;
	}

	// Map<String, Book> getBookMap()
	// HashMap을 생성하여, Books의 book들을 모두 맵<제목, Book>에 넣고 반환
	public Map<String, Book> getBookMap() {
		Map<String, Book> map = new HashMap<>();
		for (Book book : getBooks()) {
			map.put(book.getTitle(), book);
		}
		return map;
	}

	// TreeMap<String, Book> getBookTreeMap()
	// TreeMap을 생성하여, Books의 book들을 모두 트리맵<제목, Book>에 넣고 반환
	public TreeMap<String, Book> getBookTreeMap() {
		TreeMap<String, Book> treeMap = new TreeMap<>();
		for (Book book : getBooks()) {
			treeMap.put(book.getTitle(), book);
		}
		return treeMap;
	}

	// TreeSet getBookTreeSet()
	// TreeSet을 생성하여, Books의 book들을 모두 트리셋<Book>에 넣고 반환
	public TreeSet<Book> getBookTreeSet() {
		TreeSet<Book> bookTreeSet = new TreeSet<>(BookComparator.byTitle());
		bookTreeSet.addAll(getBooks());
		return bookTreeSet;
//		TreeSet<Book> bookTreeSet = new TreeSet<>(books);
//		return bookTreeSet;
	}

	public List<Book> getBooks() {
		return books;
	}

	public void setBooks(List<Book> books) {
		this.books = books;
	}

}

 

이런 형식으로 되어있다.

 

그 중 TreeSet을 출력하는데 초반에 내가 작성한 코드는 아래와 같다.

	// TreeSet getBookTreeSet()
	// TreeSet을 생성하여, Books의 book들을 모두 트리셋<Book>에 넣고 반환
	public TreeSet<Book> getBookTreeSet() {
		TreeSet<Book> bookTreeSet = new TreeSet<>(getBooks());
		return bookTreeSet;
	}

 

위에 모든 메소드들과 동일하게 getBooks()로 책 목록을 받아와 TreeSet 형태로 반환하려고 했다.

그런데 classcastexception 오류가 생기는 것이다.

 

 

class cast exception 오류를 살펴보면,

Book 클래스가 Comparable를 cast할 수 없다고 나온다.

 

구글링도 해보고 gpt에게도 물어본 결과 이해할 수가 있었다.

 

TreeSet은 데이터를 넣었을 때 정렬을 해주는 자료구조이기 때문에 해당 객체의 정렬 기준이 필요하다.
하지만 Book에는 여러 필드가 존재하므로 어떤 기준으로 정렬할지 모르겠다는 예외를 발생시킨 것이다.

 

그러므로 정렬 기준을 직접 설정해줘야 한다는 것이다.

 

public TreeSet<Book> getBookTreeSet() {
		TreeSet<Book> bookTreeSet = new TreeSet<>(BookComparator.byTitle());
		bookTreeSet.addAll(getBooks());
		return bookTreeSet;
	}

 

그래서 이렇게 제목으로 정렬하는 것을 기본 기준으로 두니까 제대로 콘솔에 찍혔다.

처음 겪어본 에러인데, 그래도 쌤에게 잘 물어보고, 여러 글들을 찾아서 해결하니 나름 뿌듯하다.

 

 


참고한 글들

https://hoonsb.tistory.com/48

 

[Java] TreeSet에서 커스텀 객체 정렬

궁금증이 들어서 코드를 쳐보다가 알게 된 점이 있어서 TreeSet에 대해서 기록해두고자 합니다. 기본적으로 Set은 중복을 허용하지 않는 자료구조입니다. 여기에 Tree가 붙으면서 이진 탐색 트리(bin

hoonsb.tistory.com

https://www.geeksforgeeks.org/how-to-fix-java-lang-classcastexception-in-treeset-by-using-custom-comparator-in-java/

 

How to Fix java.lang.ClassCastException in TreeSet By Using Custom Comparator in Java? - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

728x90