Annotation이란? 사전적 의미로는 주석이라는 뜻이다.

자바에서 Annotation은 코드 사이에 주석처럼 쓰이며 특별한 의미, 기능을 수행하도록 하는 기술이다.

즉, 프로그램에게 추가적인 정보를 제공해 주는 메타데이터(meta data)라고 볼 수 있다.(meta data : 데이터를 위한 데이터)

다음은 어노테이션의 용도를 나타낸 것이다.

1. 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보를 제공한다.

2. 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보를 제공한다.

3. 실행 시(런타임 시)특정 기능을 실행하도록 정보를 제공한다.

기본적으로 어노테이션을 사용하는 순서는 다음과 같다.

1. 어노테이션을 정의

2. 클래스에 어노테이션을 배치

3. 코드가 실행되는 중 Reflection(프로그램이 실행 중에 자신의 구조와 동작을 검사하고, 조사하고, 수정하는 것)을 이용하여 추가 정보를 획득하여 기능을 실시

 

Annotation 종류

 

@ComponentScan

@Component, @Service, @Repository, @Controller, @Configuration이 붙은 클래스 Bean들을 찾아서 Context에 bean등록을 해주는 Annotation

 

@Component

개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 Annotation

 

@Bean

개발자가 직접 제어가 불가능한 외부 라이브러리등을 Bean으로 만들려할 때 사용되는 Annotation

 

@Autowired

field, setter method, constructor에서 사용하며 Type에 따라 알아서 Bean을 주입 해준다.

Controller 클래스에서 DAO나 Service에 관한 객체들을 주입 시킬 때 많이 사용

 

Bean을 주입받는 3가지 방식

1. @Autowired

2. setter

3. 생성자(@AllArgsConstructor 사용) -> 권장방식

 

@Inject

@Autowired 어노테이션과 비슷한 역할

 

@Controller

Spring의 Controller를 의미하며, Spring MVC에서 Controller 클래스에 쓰인다.

 

@RestController

Spring에서 Controller 중 View로 응답하지 않는, Controller를 의미

method의 반환 결과를 JSON 형태로 반환

 

@Controller 와 @RestController 차이

@Controller
API와 view를 동시에 사용하는 경우에 사용
대신 API 서비스로 사용하는 경우는 @ResponseBody를 사용하여 객체를 반환
view(화면) return이 주목적

@RestController
view가 필요없는 API만 지원하는 서비스에서 사용
Spring 4.0.1부터 제공
@RequestMapping 메서드가 기본적으로 @ResponseBody 의미를 가정
data(json, xml 등) return이 주목적

즉, @RestController = @Controller + @ResponseBody

 

@Service

Service Class에서 쓰인다. 비즈니스 로직을 수행하는 Class라는 것을 나타내는 용도

 

@Repository

DAO Class(DataBase에 접근하는 method를 가지고 있는 Class)에서 쓰인다.

 

@EnableAutoConfiguration

Spring Application Context를 만들 때 자동으로 설정하는 기능을 켠다.

(classpath의 내용에 기반해서 자동으로 생성, 만약 tomcat-embed-core.jar가 존재하면 톰캣 서버가 setting)

 

@Configuration

@Configuration을 클래스에 적용하고 @Bean을 해당 Class의 method에 적용하면 @Autowired로 Bean을 부를 수 있다.

 

@Required

setter method에 적용해주면 Bean 생성시 필수 프로퍼티 임을 알린다.

 

@Qualifier("id")

@Autowired와 같이 쓰이며, 같은 타입의 Bean 객체가 있을 때 해당 아이디를 적어 원하는 Bean이 주입될 수 있도록 한다.

 

@Resource

@Autowired와 마찬가지로 Bean 객체를 주입해주는데 차이점이 있다.

Autowired는 타입으로, Resource는 이름으로 연결한다.

 

@PostConstruct, @PreConstruct

의존하는 객체를 생성한 이후 초기화 작업을 위해 객체 생성 전/후에 실행해야 할 method 앞에 붙인다.

 

@PreDestroy

객체를 제거하기 전에 해야할 작업을 수행하기 위해 사용

 

@PropertySource

해당 프로퍼티 파일을 Environment로 로딩하게 해준다.

 

@ConfigurationProperties

yaml파일 읽는다. default로 classpath:application.properties 파일이 조회

 

@Lazy

지연로딩을 지원

@Component나 @Bean Annotation과 같이 쓰는데 Class가 로드될 때 스프링에서 바로 bean등록을 마치는 것이 아니라 실제로 사용될 때 로딩이 이뤄지게 하는 방법

 

@Value

properties에서 값을 가져와 적용할 때 사용

 

@SpringBootApplication

@Configuration, @EnableAutoConfiguration, @ComponentScan 3가지를 하나의 어노테이션으로 합친 것

 

@RequestMapping

요청 URL을 어떤 method가 처리할지 mapping해주는 Annotation

 

@CookieValue

쿠키 값을 parameter로 전달 받을 수 있는 방법

 

@CrossOrigin

CORS 보안상의 문제로 브라우저에서 리소스를 현재 origin에서 다른 곳으로의 AJAX요청을 방지하는 것

 

@ModelAttribute

view에서 전달해주는 parameter를 Class(VO/DTO)의 멤버 변수로 binding 해주는 Annotation

 

@GetMapping

@RequestMapping(Method=RequestMethod.GET)과 같다.

 

@SessionAttributes

Session에 data를 넣을 때 쓰는 Annotation

 

@Valid

유효성 검증이 필요한 객체임을 지정

 

@InitBinder

@Valid 어노테이션으로 유효성 검증이 필요하다고 한 객체를 가져오기전에 수행해야할 method를 지정

 

@RequestAttribute

Request에 설정되어 있는 속성 값을 가져올 수 있다.

 

@RequestBody

요청이 온 데이터(JSON이나 XML형식)를 바로 Class나 model로 매핑하기 위한 Annotation

 

@RequestHeader

Request의 header값을 가져올 수 있다. 메소드의 파라미터에 사용

 

@RequestParam

@PathVariable과 비슷, request의 parameter에서 가져오는 것

 

@RequestPart

Request로 온 MultipartFile을 바인딩

 

@ResponseBody

HttpMessageConverter를 이용하여 JSON 혹은 xml로 요청에 응답할 수 있게 해주는 Annotation

 

@PathVariable

method parameter 앞에 사용하면서 해당 URL에서 {특정값}을 변수로 받아 올 수 있다.

 

@ExceptionHandler

해당 클래스의 예외(Exception)를 캐치하여 처리

 

@ControllerAdvice

Class 위에 ControllerAdvice를 붙이고 어떤 예외를 잡아낼 것인지는 각 메소드 상단에

@ExceptionHandler(예외클래스명.class)를 붙여서 기술

 

@RestControllerAdvice

@ControllerAdvice + @ResponseBody

 

@ResponseStatus

사용자에게 원하는 response code와 reason을 return해주는 Annotation

 

@EnableEurekaServer

Eureka 서버로 만들어준다.

 

@EnableDiscoveryClient

Eureka 서버에서 관리될 수 있는 클라이언트 임을 알려주기위한 Annotation

 

@Transactional

데이터베이스 트랜잭션을 설정하고 싶은 method에 이 Annotation을 적용하면 method 내부에서 일어나는 데이터베이스 로직이 전부 성공하거나, 데이터베이스 접근중 하나라도 실패하면 다시 롤백할 수 있게 해주는 Annotation

 

@Cacheable

method 앞에 지정하면 해당 method를 최초에 호출하면 캐시에 적재하고 다음부터는 동일한 method 호출이 있을 때 캐시에서 결과를 가져와서 return하므로 method 호출 횟수를 줄여주는 Annotation

 

@CachePut

캐시를 업데이트하기 위해서 method를 항상 실행하게 강제하는 Annotation

 

@CacheEvict

캐시에서 데이터를 제거하는 트리거(Trigger)로 동작하는 method에 붙이는 Annotation

 

@CacheConfig

클래스 레벨에서 공통의 캐시설정을 공유하는 기능

 

@Scheduled

Linux의 crontab처럼 정해진 시간에 실행해야하는 경우에 사용

 

Lombok Annotation 종류

 

@NoArgsConstructor

기본 생성자를 자동으로 추가

 

@AllArgsConstructor

모든 필드 값을 파라미터로 받는 생성자를 추가

 

@RequiredArgsConstructor

final(값이 할당되면 더 이상 변경할 수 없음) 이나 @NonNull인 필드 값만 파라미터로 받는 생성자를 추가

 

@Getter

Class 내 모든 필드의 Getter method를 자동 생성

 

@Setter

Class 내 모든 필드의 Setter method를 자동 생성

 

@ToString

Class 내 모든 필드의 toString method를 자동 생성

 

@EqualsAndHashCode

equals와 hashCode method를 오버라이딩 해주는 Annotation

 

@Builder

어느 필드에 어떤 값을 채워야 할지 명확하게 정하여 생성 시점에 값을 채워준다.

 

Constructor 와 @Builder 차이

생성 시점에 값을 채워주는 역할은 똑같다. 하지만 Builder를 사용하면 어느 필드에 어떤 값을 채워야 할지 명확하게

인지할 수 있다. 해당 Class의 Builder 패턴 Class를 생성 후 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함

 

@Data

@Getter, @Setter, @EqualsAndHashCode, @AllArgsConstructor을 포함한 Lombok에서 제공하는 필드와 관련된

모든 코드를 생성

 

JPA Annotation 종류

 

@Entity

실제 DB의 테이블과 매칭될 Class임을 명시

즉, 테이블과 링크될 클래스임을 나타냄

 

@Table

Entity Class에 매핑할 테이블 정보를 알려줌

 

@Id

해당 테이블의 PK 필드를 나타냄

 

@GeneratedValue

PK의 생성 규칙을 나타냄

 

@Column

테이블의 컬럼을 나타내며, 굳이 선언하지 않더라도 해당 Class의 필드는 모두 컬럼이 됨

'Java > 참고자료' 카테고리의 다른 글

[Java] Equals & HashCode  (0) 2022.11.25
[Java] Exception  (0) 2022.11.25
[Java] Comparable & Comparator  (0) 2022.11.25
[Java] 연산자  (0) 2022.11.25
[Java] Stack, Queue, Deque  (0) 2022.11.25

<객체 비교>

== : 동일성 비교(객체 인스턴스의 주소 값을 비교)

equals() : 동등성 비교(객체 내부의 값을 비교)

 

hashCode() : 객체의 메모리 번지를 이용해서 해시코드를 만들고 그 값을 리턴(객체마다 다른 값을 가지고 있다.)

hashCode()를 사용하는 이유 중 하나는, 객체를 비교할 때 드는 비용을 낮추기 위함이다.

자바에서 2개의 객체가 같은지 비교할 때 equals()를 사용하는데, 여러 객체를 비교할 때 equals()를 사용하면 Integer를 비교하는 것에 비해 많은 시간이 소요된다.

hashCode() 메소드를 실행하여 리턴된 해시코드 값이 다르면 다른 객체로 판단하고, 해시코드 값이 같으면 equals() 메소드로 두 객체를 다시 비교한다.

즉, 여러 객체의 동등성 비교를 할 때
hashCode() 메소드를 실행해 값이 같을 경우에만 equals() 메소드로 동등성을 비교하면 되는 것이다.
hashCode() 값이 다르면 애초에 비교할 필요가 없게 된다.

 

hashCode가 다르면, 두개의 객체가 같지 않다.

hashCode가 같으면, 두개의 객체가 같거나 다를 수 있다.

 

<equals()와 hashCode()를 같이 재정의해야 하는 이유>

1. hashCode()를 재정의 하지 않으면 같은 값 객체라도 해시값이 다를 수 있다. 따라서 HashTable에서 해당 객체가 저장된 버킷을 찾을 수 없다.

2. equals()를 재정의하지 않으면 hashCode()가 만든 해시값을 이용해 객체가 저장된 버킷을 찾을 수는 있지만 해당 객체가 자신과 같은 객체인지 값을 비교할 수 없기 때문에 null을 리턴하게 된다.

 

<equals()만 재정의>

public class Test {
	String name;
	
	public Test(String name) {
		this.name = name;
	}

	@Override
	public boolean equals(Object obj) {
		Test otherTest = (Test) obj;
		return (this.name.equals(otherTest.name));
	}
}
import java.util.HashMap;

public class EqualsAndHashCode {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str1 = "Z@S.ME";
		String str2 = "Z@RN.E";
		
		HashMap<String, Integer> hm1 = new HashMap<>();
		
		hm1.put(str1, 30);
		hm1.put(str2, 40);
		System.out.println(str1.equals(str2)); // false
		System.out.println(str1.hashCode()); // -1656719047
		System.out.println(str2.hashCode()); // -1656719047
		System.out.println(hm1.size()); // 2
		System.out.println(hm1.get(str1)); // 30
		System.out.println(hm1.get(str2)); // 40
		
		Test test1 = new Test("abcd");
		Test test2 = new Test(new String("abcd"));
		
		HashMap<Test, Integer> hm2 = new HashMap<>();
		
		hm2.put(test1, 10);
		hm2.put(test2, 20);
		System.out.println(test1.equals(test2)); // true
		System.out.println(test1.hashCode()); // 474675244
		System.out.println(test2.hashCode()); // 932583850
		System.out.println(hm2.size()); // 2
		System.out.println(hm2.get(test1)); // 10
		System.out.println(hm2.get(test2)); // 20
	}
}

<hashcode()만 재정의>

public class Test {
	String name;
	
	public Test(String name) {
		this.name = name;
	}
	
	@Override
	public int hashCode() {
		int hashCode = 0;
		hashCode = 31 * hashCode + ((name == null) ? 0 : name.hashCode());
		return hashCode;
	}
}
import java.util.HashMap;

public class EqualsAndHashCode {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str1 = "Z@S.ME";
		String str2 = "Z@RN.E";
		
		HashMap<String, Integer> hm1 = new HashMap<>();
		
		hm1.put(str1, 30);
		hm1.put(str2, 40);
		System.out.println(str1.equals(str2)); // false
		System.out.println(str1.hashCode()); // -1656719047
		System.out.println(str2.hashCode()); // -1656719047
		System.out.println(hm1.size()); // 2
		System.out.println(hm1.get(str1)); // 30
		System.out.println(hm1.get(str2)); // 40
		
		Test test1 = new Test("abcd");
		Test test2 = new Test(new String("abcd"));
		
		HashMap<Test, Integer> hm2 = new HashMap<>();
		
		hm2.put(test1, 10);
		hm2.put(test2, 20);
		System.out.println(test1.equals(test2)); // false
		System.out.println(test1.hashCode()); // 2987074
		System.out.println(test2.hashCode()); // 2987074
		System.out.println(hm2.size()); // 2
		System.out.println(hm2.get(test1)); // 10
		System.out.println(hm2.get(test2)); // 20
	}
}

<equals()와 hashcode() 모두 재정의>

public class Test {
	String name;
	
	public Test(String name) {
		this.name = name;
	}

	@Override
	public boolean equals(Object obj) {
		Test otherTest = (Test) obj;
		return (this.name.equals(otherTest.name));
	}
	
	@Override
	public int hashCode() {
		int hashCode = 0;
		hashCode = 31 * hashCode + ((name == null) ? 0 : name.hashCode());
		return hashCode;
	}
}
import java.util.HashMap;

public class EqualsAndHashCode {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str1 = "Z@S.ME";
		String str2 = "Z@RN.E";
		
		HashMap<String, Integer> hm1 = new HashMap<>();
		
		hm1.put(str1, 30);
		hm1.put(str2, 40);
		System.out.println(str1.equals(str2)); // false
		System.out.println(str1.hashCode()); // -1656719047
		System.out.println(str2.hashCode()); // -1656719047
		System.out.println(hm1.size()); // 2
		System.out.println(hm1.get(str1)); // 30
		System.out.println(hm1.get(str2)); // 40
		
		Test test1 = new Test("abcd");
		Test test2 = new Test(new String("abcd"));
		
		HashMap<Test, Integer> hm2 = new HashMap<>();
		
		hm2.put(test1, 10);
		hm2.put(test2, 20);
		System.out.println(test1.equals(test2)); // true
		System.out.println(test1.hashCode()); // 2987074
		System.out.println(test2.hashCode()); // 2987074
		System.out.println(hm2.size()); // 1
		System.out.println(hm2.get(test1)); // 20
		System.out.println(hm2.get(test2)); // 20
	}
}

equals()만 재정의 : equals()가 true이고, hashCode()가 다른 경우 => HashMap에서 다른 key로 인식

hashCode()만 재정의 : equals()가 false이고, hashCode()가 같은 경우 => HashMap에서 다른 key로 인식

equals()와 hashCode() 모두 재정의 : equals()가 true이고, hashCode()가 같은 경우 => HashMap에서 같은 key로 처리

'Java > 참고자료' 카테고리의 다른 글

[Java] Annotation  (0) 2023.08.15
[Java] Exception  (0) 2022.11.25
[Java] Comparable & Comparator  (0) 2022.11.25
[Java] 연산자  (0) 2022.11.25
[Java] Stack, Queue, Deque  (0) 2022.11.25
public class ExceptionOccurred {
	
	// Checked Exception : RuntimeException을 상속받지 않은 클래스
	// Unchecked Exception : RuntimeException을 상속받은 클래스
	// throw : 강제로 예외를 발생시킬 수 있음 단, 발생시킨 예외를 catch문에서 잡을 수 있는 처리가 되어있지 않으면 오류 발생(catch문의 Exception은 모든 예외를 잡을 수 있음)
	// throws : 예외 발생 시 자신을 호출한 상위 메소드로 예외를 던짐(특정 상위 메소드에서 예외를 한 번에 처리하는 경우가 있을 수 있음, 계속 throws로 던질 경우 최종적으로 JVM이 처리를 하게 되지만, 권장하지 않음)
	// 중요 : RuntimeException을 상속받은 Unchecked Exception의 경우 throws는 아무 의미 없음, throws는 Checked Exception의 처리 방법 중 하나
	
	public void method1() throws Exception {
		// 이 메소드를 호출한 부분의 catch문에 Exception에 대한 에외 처리가 있어야 함
		throw new Exception("강제로 예외 발생"); // 모든 예외를 잡을 수 있는 Exception의 경우 throws Exception 필수
	}
	
	// RuntimeException을 상속받은 NullPointerException
	public void method2() {
		// 이 메소드를 호출한 부분의 catch문에 Exception 또는 NullPointerException에 대한 예외 처리가 있어야 함
		throw new NullPointerException("강제로 NullPointerException 발생"); // NullPointerException 발생
	}
	
	// RuntimeException을 상속받은 ArithmeticException
	public void method3() {
		// 이 메소드를 호출한 부분의 catch문에 Exception 또는 ArithmeticException에 대한 예외 처리가 있어야 함
		System.out.println(3 / 0); // ArithmeticException 발생
	}
	
	// RuntimeException을 상속받은 NullPointerException 발생이므로 throws는 아무 의미 없음
	public void method4() throws ArithmeticException {
		throw new NullPointerException("강제로 NullPointerException 발생"); // NullPointerException 발생
	}
	
	// RuntimeException을 상속받은 NullPointerException 발생이므로 throws는 아무 의미 없음
	public void method5() throws ArithmeticException {
		String name = null;
		System.out.println(name.length());
	}
	
	// ArithmeticException : 어떤 수를 0으로 나눌 때 발생(RuntimeException 상속)
	// NullPointerException : NULL 객체를 참조할 때 발생(RuntimeException 상속)
	// ClassCastException : 적절하지 못하게 클래스를 형 변환하는 경우 발생(RuntimeException 상속)
	// NegativeArraySizeException : 배열의 크기가 음수 값인 경우 발생(RuntimeException 상속)
	// IndexOutOfBoundsException : 리스트형 객체에서 선언되지 않은 요소를 가져오려고 할 때 발생(RuntimeException 상속)
}
public class ExceptionTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String name = null;
		
		ExceptionOccurred exceptionOccurred = new ExceptionOccurred();
		
		try {
			int nameLength = name.length(); // 1. NullPointerException에 걸리고 finally 실행
			int num = 3 / 0; // 2. 코드 1이 없다면 ArithmeticException에 걸리고 finally 실행
			exceptionOccurred.method2(); // 3. 코드 1, 2가 없다면 NullPointerException에 걸리고 finally 실행
			exceptionOccurred.method3(); // 4. 코드 1, 2, 3이 없다면 ArithmeticException에 걸리고 finally 실행
		} catch (NullPointerException e) {
			System.out.println("NullPointerException : " + e.getMessage());
		} catch (ArithmeticException e1) {
			System.out.println("ArithmeticException : " + e1.getMessage());
		} catch (Exception e) { // try문 실행에서 발생하는 예외 중 NullPointerException, ArithmeticException 외의 예외는 이곳에 걸림
			System.out.println("Exception : 모든 예외를 잡을 수 있음");
		} finally { // 무조건 실행시킬 코드를 적는 부분
			System.out.println("무조건 실행되는 부분");
		}
		
		try {	
			int nameLength = name.length(); // 1. Exception에 걸리고 finally 실행
			int num = 3 / 0; // 2. 코드 1이 없다면 Exception에 걸리고 finally 실행
			exceptionOccurred.method1(); // 3. 코드 1, 2가 없다면 Exception에 걸리고 finally 실행
			throw new Exception("강제 예외 발생"); // 4. 코드 1, 2, 3이 없다면 Exception에 걸리고 finally 실행
//			exceptionOccurred.method2(); // 5. 코드 1, 2, 3, 4가 없다면 Exception에 걸리고 finally 실행
//			exceptionOccurred.method3(); // 6. 코드 1, 2, 3, 4, 5가 없다면 Exception에 걸리고 finally 실행
		} catch (Exception e) { // try문 실행에서 발생하는 모든 예외를 잡을 수 있지만, 어떤 문제로 발생하는 예외인지 확인이 불가하다는 단점이 있다.
			System.out.println("Exception : 모든 예외를 잡을 수 있음");
		} finally { // 무조건 실행시킬 코드를 적는 부분
			System.out.println("무조건 실행되는 부분");
		}
	}
}

Checked Exception : RuntimeException을 상속받지 않은 클래스

Unchecked Exception : RuntimeException을 상속받은 클래스

throw : 강제로 예외를 발생시킬 수 있음 단, 발생시킨 예외를 catch문에서 잡을 수 있는 처리가 되어있지 않으면 오류 발생(catch문의 Exception은 모든 예외를 잡을 수 있음)

throws : 예외 발생 시 자신을 호출한 상위 메소드로 예외를 던짐(특정 상위 메소드에서 예외를 한 번에 처리하는 경우가 있을 수 있음, 계속 throws로 던질 경우 최종적으로 JVM이 처리를 하게 되지만, 권장하지 않음)

 

중요 : RuntimeException을 상속받은 Unchecked Exception의 경우 throws는 아무 의미 없음

throws는 Checked Exception의 처리 방법 중 하나

 

 

'Java > 참고자료' 카테고리의 다른 글

[Java] Annotation  (0) 2023.08.15
[Java] Equals & HashCode  (0) 2022.11.25
[Java] Comparable & Comparator  (0) 2022.11.25
[Java] 연산자  (0) 2022.11.25
[Java] Stack, Queue, Deque  (0) 2022.11.25

Comparable : 현재 객체와 다른 객체의 비교 기준을 정함 => Comparable - CompareTo (T o) 정의

Comparator : 두 객체의 비교 기준을 정함 => Comparator - Compare(T o1, T o2) 정의

 

<Comparable>

public class Node implements Comparable<Node> {
	
	private int index = 0; // 노드의 번호
	private int distance = 0; // 노드의 거리
	private String name = ""; // 노드의 이름
	
	public Node(int index, int distance, String name) {
		this.index = index;
		this.distance = distance;
		this.name = name;
	}
	
	public int getIndex() {
		return this.index;
	}
	
	public int getDistance() {
		return this.distance;
	}
	
	public String getName() {
		return this.name;
	}

	@Override
	public int compareTo(Node otherNode) {
		// TODO Auto-generated method stub
		// private 변수이지만 클래스 내부에선 getDistance()로 가져올 필요 없이 직접 가져와도 됨
//		return this.distance - otherNode.distance; // distance 기준 오름차순 정렬 // 1, 2, 3, ...
//		return this.getDistance() - otherNode.getDistance(); // distance 기준 오름차순 정렬 // 1, 2, 3, ...
//		return otherNode.distance - this.distance; // distance 기준 내림차순 정렬 // ..., 3, 2, 1
//		return otherNode.getDistance() - this.getDistance(); // distance 기준 내림차순 정렬 // ..., 3, 2, 1
		
		// distance, index, name 기준 오름차순 정렬(ORDER BY distance, index, name)
		if (this.distance == otherNode.distance) { // distance가 같을 경우
			
			if (this.index == otherNode.index) { // index가 같을 경우
				return this.name.compareTo(otherNode.name); // name 기준 오름차순 정렬
//				return otherNode.name.compareTo(this.name); // name 기준 내림차순 정렬
			} else { // index가 같지 않을 경우
				return this.index - otherNode.index; // index 기준 오름차순 정렬
//				return otherNode.index - this.index; // index 기준 내림차순 정렬
			}
		} else { // distance가 같지 않을 경우
			return this.distance - otherNode.distance; // distance 기준 오름차순 정렬
//			return otherNode.distance - this.distance; // distance 기준 내림차순 정렬
		}
		
//		// int 값으로 비교 : return int - int;
//		// String 값으로 비교 : return String.compareTo(String);
//		------------------------------------------------------------------------------------------------------
//		// distance 값을 기준으로 오름차순 정렬을 시키는 다른 방법 1, 2, 3, ...
//		if (this.distance < otherNode.distance) {
//			return -1; // 해당 노드의 거리가 비교대상 노드의 거리보다 작다면 => 해당 노드가 더 작다 리턴
//		}
//		
//		return 1; // 해당 노드의 거리가 비교대상 노드의 거리보다 크거나 같다면 => 해당 노드가 더 크다 리턴
//		
//		// distance 값을 기준으로 내림차순 정렬을 시키는 다른 방법 ..., 3, 2, 1
//		if (this.distance < otherNode.distance) {
//			return 1; // 해당 노드의 거리가 비교대상 노드의 거리보다 작다면 => 해당 노드가 더 크다 리턴
//		}
//		
//		return -1; // 해당 노드의 거리가 비교대상 노드의 거리보다 크거나 같다면 => 해당 노드가 더 작다 리턴
//		
//		// int 값으로 비교 : 1(크다), 0(같다), -1(작다)
//		// String 값으로 비교 : 0(같다), 다양한 양수/음수 값 : 대상 문자열의 제일 앞 부분부터 비교하여 비교대상 문자열을 포함한다면 문자열 길이 차만큼 리턴, 하지만 아예 포함하지 않거나, 중간에 포함한다면 각 문자열의 제일 앞 아스키 코드값의 차를 리턴(대상 문자열 첫 문자 아스키코드 값 - 비교대상 문자열 첫 문자 아스키코드 값)
//		------------------------------------------------------------------------------------------------------
	}
}
import java.util.*;

public class ComparableTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// --------------------------------------일반 배열--------------------------------------
		int[] arr1 = {2, 1, 6, 3, 7, 4, 5};
		
		for (int num : arr1) {
			System.out.print(num + " "); // 2 1 6 3 7 4 5 
		}
		
		System.out.println();
		// --------------------------------------배열 정렬--------------------------------------
		Arrays.sort(arr1); // 기본 오름차순 정렬
		
		for (int num : arr1) {
			System.out.print(num + " "); // 1 2 3 4 5 6 7 
		}
		
		System.out.println();
		// ------------------------Comparable 인터페이스를 구현한 Node 클래스------------------------
		ArrayList<Node> list = new ArrayList<>();
		
		// index, distance, name
		list.add(new Node(1, 2, "B"));
		list.add(new Node(2, 1, "A"));
		list.add(new Node(2, 2, "C"));
		list.add(new Node(1, 3, "F"));
		list.add(new Node(1, 3, "E"));
		list.add(new Node(1, 3, "D"));
		
		for (Node node : list) {
			System.out.print(node.getName() + " "); // "B", "A", "C", "F", "E", "D"
		}
		
		System.out.println();
		// -----------------------------------Node 클래스 정렬-----------------------------------
		Collections.sort(list); // Node 클래스의 정렬 기준 : ORDER BY distance, index, name
		
		for (Node node : list) {
			System.out.print(node.getName() + " "); // "A", "B", "C", "D", "E", "F"
		}
	}
}

<Comparator>

public class Node {
	
	private int index = 0; // 노드의 번호
	private int distance = 0; // 노드의 거리
	
	public Node(int index, int distance) {
		this.index = index;
		this.distance = distance;
	}
	
	public int getIndex() {
		return this.index;
	}
	
	public int getDistance() {
		return this.distance;
	}
}
import java.util.*;

public class ComparatorTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// -------------------------------------Node 클래스-------------------------------------
		ArrayList<Node> list = new ArrayList<>();
		
		list.add(new Node(2, 2));
		list.add(new Node(1, 1));
		list.add(new Node(3, 3));
		
		for (Node node : list) {
			System.out.print(node.getDistance() + " "); // 2, 1, 3
		}
		
		System.out.println();
		// -----------------------------------Node 클래스 정렬-----------------------------------
		Collections.sort(list, new Comparator<Node>() {
			@Override
			public int compare(Node node1, Node node2) {
				// distance 기준 오름차순 정렬 // 1, 2, 3, ...
				if(node1.getDistance() < node2.getDistance()) return -1;
				else if(node1.getDistance() == node2.getDistance()) return 0;
				else return 1;
				
				// distance 기준 내림차순 정렬 // ..., 3, 2, 1
//				if(node1.getDistance() < node2.getDistance()) return 1;
//				else if(node1.getDistance() == node2.getDistance()) return 0;
//				else return -1;
				
				// distance는 Node 클래스의 private 변수이므로 node1.distance가 아닌 distance 값을 가져오도록 만든 node1.getDistance() 메소드 사용
			}
		});
		
		for (Node node : list) {
			System.out.print(node.getDistance() + " "); // 1, 2, 3
		}
	}
}

<2차원 배열에서 다중 정렬>

int[][] arr = {{1, 3}, {1, 2}, {3, 4}, {1, 4}, {2, 4}};

Arrays.sort(arr, new Comparator<int[]>() {
    @Override
    public int compare(int[] o1, int[] o2) {
        if(o1[0] == o2[0]) { // 앞 원소가 같을 경우
            return o1[1] - o2[1]; // 뒤 원소 기준 오름차순
//          return o2[1] - o1[1]; // 뒤 원소 기준 내림차순
        }else { // 앞 원소가 같지 않을 경우
            return o1[0] - o2[0]; // 앞 원소 기준 오름차순
//          return o2[0] - o1[0]; // 앞 원소 기준 내림차순
        }
    }
});

 

 

<Comparable 인터페이스의 compareTo 메소드 구현 시 타입 비교>

 

'Java > 참고자료' 카테고리의 다른 글

[Java] Equals & HashCode  (0) 2022.11.25
[Java] Exception  (0) 2022.11.25
[Java] 연산자  (0) 2022.11.25
[Java] Stack, Queue, Deque  (0) 2022.11.25
[Java] 참고자료  (0) 2022.11.25

<비트 연산자>

// 비트 연산자
System.out.println(1 << 5); // 1 -> 100000 // 32
System.out.println(2 << 5); // 10 -> 1000000 // 64
System.out.println(10 >> 1); // 1010 -> 101 // 5
System.out.println(10 >> 2); // 1010 -> 10 // 2
System.out.println(1 << 5 & 1 << 3); // 100000 & 1000 // 모두 1인 경우만 1로 => 000000 // 0
System.out.println(13 & 9); // 1101 & 1001 // 모두 1인 경우만 1로 => 1001 // 9
System.out.println(1 << 5 | 1 << 3); // 100000 | 1000 // 하나라도 1이면 1로 => 101000 // 40
System.out.println(13 | 9); // 1101 | 1001 // 하나라도 1이면 1로 => 1101 // 13
System.out.println(13 ^ 9); // 1101 ^ 1001 // 모두 같으면 0, 다르면 1로 => 100 // 4
System.out.println(~13); // ~1101 // 8비트로 만든 후 0과 1 바꿈 => 00001101 => 11110010 // -14
// 2의 보수 = 1의 보수(0과 1 바꿈) + 1
// 10진수 -14를 2진수로 표현
// 14를 8비트로 만든다. 00001110
// -14는 음수이므로 첫 번째 부호 비트를 1로 바꾼다. 10001110
// 부호 비트만 그대로 유지하고 0과 1을 바꾼다.(1의 보수) 11110001
// 1을 더한다. 11110010

'Java > 참고자료' 카테고리의 다른 글

[Java] Exception  (0) 2022.11.25
[Java] Comparable & Comparator  (0) 2022.11.25
[Java] Stack, Queue, Deque  (0) 2022.11.25
[Java] 참고자료  (0) 2022.11.25
[Java] 소수  (0) 2022.11.25
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class DequeSample {
	
	// Stack, Queue, Deque

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Deque<Integer> stack1 = new ArrayDeque<>(); // addFirst + removeFirst // 스택
		
		stack1.addFirst(1);
		stack1.addFirst(2);
		stack1.addFirst(3);
		
//		stack1.add(4); // add는 addLast와 같음 // addFirst로 쌓고 있었는데 그 방향과 반대 방향에 추가 4, 1, 2, 3이 됨
//		stack1.addFirst(5); // 1, 2, 3과 같은 방향으로 추가 // 4, 1, 2, 3, 5
//		stack1.addLast(6); // addFirst와 반대 방향으로 추가 // 6, 4, 1, 2, 3, 5
		
		System.out.println("stack1"); // stack1
		
		System.out.println(stack1.peekFirst()); // 3
		System.out.println(stack1.removeFirst()); // 3
		System.out.println(stack1.removeFirst()); // 2
		System.out.println(stack1.removeFirst()); // 1
		
		Deque<Integer> queue1 = new ArrayDeque<>(); // addFirst + removeLast // 큐
		
		queue1.addFirst(1);
		queue1.addFirst(2);
		queue1.addFirst(3);
		
		System.out.println("queue1"); // queue1
		
		System.out.println(queue1.peekLast()); // 1
		System.out.println(queue1.removeLast()); // 1
		System.out.println(queue1.removeLast()); // 2
		System.out.println(queue1.removeLast()); // 3
		
		Deque<Integer> queue2 = new ArrayDeque<>(); // addLast + removeFirst // 큐
		
		queue2.addLast(1);
		queue2.addLast(2);
		queue2.addLast(3);
		
		System.out.println("queue2"); // queue2
		
		System.out.println(queue2.peekFirst()); // 1
		System.out.println(queue2.removeFirst()); // 1
		System.out.println(queue2.removeFirst()); // 2
		System.out.println(queue2.removeFirst()); // 3
		
		Deque<Integer> stack2 = new ArrayDeque<>(); // addLast + removeLast // 스택
		
		stack2.addLast(1);
		stack2.addLast(2);
		stack2.addLast(3);
		
		System.out.println("stack2"); // stack2
		
		System.out.println(stack2.peekLast()); // 3
		System.out.println(stack2.removeLast()); // 3
		System.out.println(stack2.removeLast()); // 2
		System.out.println(stack2.removeLast()); // 1
		
		// Deque 자료구조에서 확인할 수 있는 사실
		// add(A) + peek(B) or remove(B)가 있을 때 // (A)와 (B)는 First 또는 Last
		// (A)와 (B)가 같다면 스택(Stack)처럼 동작
		// (A)와 (B)가 다르다면 큐(Queue)처럼 동작
		// First + First, Last + Last => 스택(Stack)
		// First + Last, Last + First => 큐(Queue)
		// addFirst로 쌓고 있는 구조에서 제일 앞에 원소를 추가하고 싶다면 addLast로 추가
		// addLast로 쌓고 있는 구조에서 제일 앞에 원소를 추가하고 싶다면 addFirst로 추가
		
		Stack<Integer> stack = new Stack<>();
		
		stack.push(1);
		stack.push(2);
		stack.push(3);
		
		System.out.println("Original Stack"); // Original Stack
		System.out.println(stack.peek()); // 3
		System.out.println(stack.pop()); // 3
		System.out.println(stack.pop()); // 2
		System.out.println(stack.pop()); // 1
		
		Queue<Integer> queue = new LinkedList<>();
		
		queue.offer(1);
		queue.offer(2);
		queue.offer(3);
		
		System.out.println("Original Queue"); // Original Queue
		System.out.println(queue.peek()); // 1
		System.out.println(queue.poll()); // 1
		System.out.println(queue.poll()); // 2
		System.out.println(queue.poll()); // 3
	}
}

<Deque 자료구조>
add(A) + peek(B) or remove(B)가 있을 때 // (A)와 (B)는 First 또는 Last
(A)와 (B)가 같다면 스택(Stack)처럼 동작
(A)와 (B)가 다르다면 큐(Queue)처럼 동작
First + First, Last + Last => 스택(Stack)
First + Last, Last + First => 큐(Queue)
addFirst로 쌓고 있는 구조에서 제일 앞에 원소를 추가하고 싶다면 addLast로 추가
addLast로 쌓고 있는 구조에서 제일 앞에 원소를 추가하고 싶다면 addFirst로 추가

'Java > 참고자료' 카테고리의 다른 글

[Java] Comparable & Comparator  (0) 2022.11.25
[Java] 연산자  (0) 2022.11.25
[Java] 참고자료  (0) 2022.11.25
[Java] 소수  (0) 2022.11.25
[Java] Class 기본 구조  (0) 2022.11.25
<JAVA>
------------------------------------------------------------------------
문자 확인 및 변환

char ch1 = 'a';

Character.isUpperCase(ch1); // 대문자 확인 : false

Character.isLowerCase(ch1); // 소문자 확인 : true

Character.isDigit(ch1); // 숫자 확인 : false

Character.toUpperCase(ch1); // 대문자 변환 : 'A'

Character.toLowerCase(ch1); // 소문자 변환 : 'a'

Character.isAlphabetic(ch1); // 영문자 확인(한글 자음, 모음 포함) : true

Character.isLetter(ch1); // 영문자 확인(한글 자음, 모음 포함) : true
------------------------------------------------------------------------
문자열 관련

String str1 = "abcd...a";

str1.length(); // 문자열 길이 : 8

str1.charAt(1); // 문자열의 해당 인덱스 값 : 'b'

"abcd...a".equals(str1); // 문자열 같은지 비교 : true

str1.toUpperCase(); // 대문자 변환 : "ABCD...A"

str1.toLowerCase(); // 소문자 변환 : "abcd...a"

str1.indexOf("a"); // 문자열 포함 확인 & 포함한다면 첫 인덱스 반환 : 0
str1.indexOf("abc"); // : 0
str1.indexOf("bc"); // : 1
str1.indexOf("bca"); // : -1 (포함하지 않으면 -1)

str1.replace("ab", "z") // 문자열 변경  : "zcd...a"
str1.replace("..", ".") // : "abcd..a"

while (str1.indexOf("..") != -1) { // ".."이 남아있는지 체크
	str1 = str1.replace("..", ".");
} // : "abcd.a"

str1.isEmpty(); // 빈 문자열인지 체크 : false

str1.substring(1); // 인덱스로 문자열 자르기(이상) : "bcd...a"
str1.substring(1,3); // (이상~미만) : "bc"

String[] str1Arr = str1.split("bc"); // 문자열 쪼개서 배열 만들기 : "a", "d...a"

str1.startsWith("ab") // "ab"로 시작하는지 확인 : true

str1.endsWith("a") // "a"로 끝나는지 확인 : true

str1.contains("cd") // "cd"를 포함하는지 확인 : true

"A".charAt(0); // 'A'
(int)"A".charAt(0); // 65
(byte)"A".charAt(0); // 65
'A' // 'A'
(int)'A'; // 65
(byte)'A'; // 65

대문자 A ~ Z : 65 ~ 90
소문자 a ~ z : 97 ~ 122
------------------------------------------------------------------------
문자열을 숫자로

String s = "123";

Integer.parseInt(s); // 123
Float.parseFloat(s); // 123.0
Double.parseDouble(s); // 123.0
------------------------------------------------------------------------
int n = 32;

String strNum3 = Integer.toString(n, 3); // 10진수를 3진수로

StringBuilder sb = new StringBuilder(strNum3); // strNum3 값을 초기값으로 가지는 sb 생성

String strNum3Reverse = sb.reverse().toString(); // 문자열 뒤집기

int answer = Integer.parseInt(strNum3Reverse, 3); // 3진수를 10진수로

sb.setLength(0); // 가장 빠른 초기화 방법

String binaryNum = Integer.toBinaryString(n); // 100000
char[] charArr = binaryNum.toCharArray(); // {'1','0','0','0','0','0'}
------------------------------------------------------------------------
String : 문자열 연산이 적고 멀티쓰레드 환경일 경우
StringBuffer : 문자열 연산이 많고 멀티쓰레드 환경일 경우
StringBuilder : 문자열 연산이 많고 단일쓰레드이거나 동기화를 고려하지 않아도 되는 경우
------------------------------------------------------------------------
절대값
int num = Math.abs(-10); // 10

제곱근값
double sqrtN = Math.sqrt(n); // 제곱근값으로 소수점이 존재하기 때문에 double
------------------------------------------------------------------------
해시맵 안에 해시셋

HashMap<String, HashSet<String>> setHashMap = new HashMap<>();

setHashMap.put("key1", new HashSet<>());
        
setHashMap.get("key1").add("value1");
setHashMap.get("key1").add("value1");
setHashMap.get("key1").add("value2");
setHashMap.get("key1").add("value3");
setHashMap.get("key1").remove("value3"); // [value2, value1]

setHashMap.containsKey("key1"); // true
------------------------------------------------------------------------
해시맵 키, 값 세팅 및 꺼내기

HashMap<String, String> strHashMap = new HashMap<>();

strHashMap.put("key1", "value1");
strHashMap.put("key1", "value2"); // value2

for (int i = 0; i < strHashMap.size(); i++) {
	String hmKey = strHashMap.keySet().toArray()[i].toString(); // put한 순서로 인덱스가 정해지진 않는다.
	String hmValue = strHashMap.values().toArray()[i].toString(); // hmKey와 순서는 일치
}
------------------------------------------------------------------------
HashMap<String, Integer> intHashMap = new HashMap<>();
        
for (int i = 0; i < genres.length; i++) {
	intHashMap.put(genres[i], intHashMap.getOrDefault(genres[i], 0) + plays[i]); // 해시맵.getOrDefault(가져올 값, 없을 경우 디폴트 값)
}
------------------------------------------------------------------------
해시셋 값 세팅 및 꺼내기

HashSet<String> hs = new HashSet<>();

hs.add("value10");
hs.add("value11");
hs.add("value12");

HashSet 출력 방법1
for (String hsValue : hs) { // 집합의 값 꺼내는 방법
	System.out.print(hsValue + ","); // value11,value10,value12,
}

HashSet 출력 방법2
Iterator it = hs.iterator();

while (it.hasNext()) {
	System.out.print(it.next() + ","); // value11,value10,value12,
}
------------------------------------------------------------------------
Hash의 특성 : 중복된 키를 허용하지 않는다.
Set의 특성 : 중복된 값을 허용하지 않는다.
------------------------------------------------------------------------
 String s = "example";
        
if (s.contains("ex")) {
	s = s.replace("ex", "xe"); // replace만 하면 안되고 담아줘야 해
}
------------------------------------------------------------------------
정렬 및 비교

String[] participant = {"leo", "kiki", "eden"};

Arrays.asList(participant); // 배열의 리스트화
Collections.frequency(리스트, 찾고자 하는 객체); // 문자열은 Object이므로 몇 개 존재하는지 찾을 수 있음

Arrays.sort(participant); // a ~ z 순서 정렬 // 숫자의 경우 1부터 정렬
Arrays.sort(participant, Collections.reverseOrder()); // z ~ a 순서 정렬 // 숫자의 경우 int[]가 아닌 Integer[]일 경우에만 가능

int[] arrA = {1, 1, 1, 6, 0};
int[] arrTempA = arrA;
Arrays.sort(arrTempA); // arrTempA 오름차순 정렬

Integer[] tempA = Arrays.stream(arrA).boxed().toArray(Integer[]::new); // int 배열인 arrA를 Integer 배열 tempA로
Arrays.sort(tempA, Collections.reverseOrder()); // tempA 내림차순 정렬
int[] arrTempA = Arrays.stream(tempA).mapToInt(Integer::intValue).toArray(); // Integer 배열인 tempA를 int 배열 arrTempA로

int[][] arr = {{5, 4}, {5, 2}, {1, 2}, {3, 1}, {1, 3}};

Arrays.sort(arr, new Comparator<int[]>() { // 2차원 배열 정렬
	@Override
	public int compare(int[] o1, int[] o2) {
		if(o1[0] == o2[0]) {
			return o1[1] - o2[1]; // 뒤 원소 오름차순 // o2[1] - o1[1] 뒤 원소 내림차순
		}else {
			return o1[0] - o2[0]; // 앞 원소 오름차순 // o2[0] - o1[0] 앞 원소 내림차순
		}
	}
});

Arrays.sort(strNumbers, new Comparator<String>() { // 숫자로 된 문자열 배열이 있을 때, 이어서 가장 큰 숫자를 만들고자 할 때 사용
	@Override
	public int compare(String o1, String o2) {
		// TODO Auto-generated method stub
		return (o2+o1).compareTo(o1+o2); // 내림차순 정렬 // 오름차순 정렬 (o1+o2).compareTo(o1+o2);
	}
});

String answer = "YES";

if ("YES".equals(answer)) // 문자열 비교는 equals로

ArrayList<String> strArrayList = new ArrayList<>();

Collections.sort(strArrayList); // 정렬

static class Music{
        String genre;
        int play;
        int idx;
        
        public Music(String genre, int play, int idx) {
            this.genre = genre;
            this.play = play;
            this.idx = idx;
        }
}

ArrayList<Music> list = new ArrayList<>();

Collections.sort(list, (o1, o2) -> o1.play - o2.play); // 오름차순 정렬
Collections.sort(list, (o1, o2) -> o2.play - o1.play); // 내림차순 정렬

int idx = Arrays.asList(strArr).indexOf("Kim");
boolean containCheck = Arrays.asList(strArr).contains("Kim");
------------------------------------------------------------------------
코딩테스트 볼 때
import java.util.*; 쓰고 시작하자
------------------------------------------------------------------------
continue; // 아래 구문으로 내려가지 않고 다시 반복문 조건으로
break; // 반복문 종료
return; // 함수 종료
------------------------------------------------------------------------
문자 치환

String match1 = "[^a-zA-Z]";

str1 = str1.replaceAll(match1, ""); // 문자열 str1에서 영문자를 제외한 모든 문자를 ""로 치환 // ^는 제외라는 의미

"[a-zA-Z]" : 영문자
"[^0-9a-zA-Z]" : 숫자, 영문자 제외
"[^\uAC00-\uD7A3]" : 특수문자 제외
"[^\uAC00-\uD7A30-9a-zA-Z]" : 특수문자, 숫자, 영문자 제외
------------------------------------------------------------------------
int[] numArr = {9, 3, 9, 3, 9, 7, 9};

Arrays.stream(numArr).sum(); // 합계 49
------------------------------------------------------------------------
System.out.println(2f); // 2.0

int i = 100;
long l1 = 100L;
long l2 = 100l;
double d1 = 1.23;
double d2 = 1.23D;
double d3 = 1.23d;
float f1 = 1.23F;
float f2 = 1.23f;
------------------------------------------------------------------------

'Java > 참고자료' 카테고리의 다른 글

[Java] Comparable & Comparator  (0) 2022.11.25
[Java] 연산자  (0) 2022.11.25
[Java] Stack, Queue, Deque  (0) 2022.11.25
[Java] 소수  (0) 2022.11.25
[Java] Class 기본 구조  (0) 2022.11.25
import java.util.Arrays;

public class PrimeNumber {
	
	// 소수(Prime Number)
	
	// x가 소수인지 체크
	public static boolean isPrimeNumber1(int x) { // 시간 복잡도 O(N)
		
		for (int i = 2; i < x; i++) { // 2부터 자기 자신 숫자전까지 체크
			
			if (x % i == 0) {
				return false;
			}
		}
		return true;
	}
	
	// 약수의 성질 : 모든 약수가 가운데 약수를 기준으로 곱셈 연산에 대해 대칭을 이룬다는 것을 이용하면 시간 복잡도를 줄일 수 있다.
	// 제곱근까지만 확인하면 된다는 것이다.
	
	// x가 소수인지 체크(더 효율적)
	public static boolean isPrimeNumber2(int x) { // 시간 복잡도 O(제곱근N)
		
		for (int i = 2; i <= Math.sqrt(x); i++) { // 2부터 제곱근 수 이하까지 체크
			
			if (x % i == 0) {
				return false;
			}
		}
		return true;
	}
	
	// 다수의 소수 판별
	// 에라토스테네스의 체 알고리즘 사용
	// 2부터 N까지의 모든 자연르르르 나열
	// 남은 수 중에서 아직 처리하지 않은 가장 작은 수 i를 찾는다.
	// 남은 수 중에서 i의 배수를 모두 제거한다. (i는 제거하지 않은다.)
	// 더 이상 반복할 수 없을 때까지 2번과 3번의 과정을 반복한다.
	
	// 26까지의 숫자 중 소수의 개수는?
	// 2를 제외한 2의 배수를 제거
	// 3을 제외한 3의 배수를 제거
	// 5를 제외한 5의 배수를 제거
	// 제곱근 26은 5와 6 사이이므로 5.xxxx (이 이하까지만 체크하면 된다.)
	// 제외되지 않은 수들은 모두 소수
	
	// x까지의 양의 정수 중 소수 나열하기
	public static void primeNumbers(int x) { // 26
		boolean[] arr = new boolean[x + 1]; // 26까지 체크해야 하므로 배열의 크기 +1
		
		Arrays.fill(arr, true); // 일단 모든 수를 소수라고 체크
		
		arr[0] = false; // 0은 소수가 아님
		arr[1] = false; // 1은 소수가 아님
		
		for (int i = 2; i <= Math.sqrt(x); i++) {
			
			// x까지의 2의 배수부터 지우자
			if (arr[i] == true) {
				
				int j = 2;
				
				while (i * j <= x) {
					arr[i * j] = false;
					j++;
				}
			}
		}
		
		for (int i = 2; i <= x; i++) {
			
			if (arr[i] == true) {
				System.out.print(i + " ");
			}
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(isPrimeNumber1(6));
		System.out.println(isPrimeNumber2(7));
		primeNumbers(26);
	}
}

소수인지 체크, 특정 숫자까지 소수 나열

'Java > 참고자료' 카테고리의 다른 글

[Java] Comparable & Comparator  (0) 2022.11.25
[Java] 연산자  (0) 2022.11.25
[Java] Stack, Queue, Deque  (0) 2022.11.25
[Java] 참고자료  (0) 2022.11.25
[Java] Class 기본 구조  (0) 2022.11.25

+ Recent posts