public interface Comparator {
int compare(Object o1, Object o2); //o1, o2 두 객체 비교
boolean equals(Object obj); //equals를 오버라이딩하라는 뜻
}
public interface Comparable {
int compareTo (Object o); // 주어진 객체 o 를 자신과 비교
}
public final class Integer extends Number implements Comparable {
...
public in t compareTo(Integer anotherInteger) {
int v1 = this.value;
int v2 = anotherInteger.value;
//같으면 0, 오른쪽값이 크면 -1, 작으면 1을 반환
return (v1 < v2 ? -1: (v1==v2? 0 :1));
}
...
}
예제 Ex11_7
import java.util.*;
class Ex11_7 {
public static void main(String[] args) {
String[] strArr = {"cat", "Dog", "lion", "tiger"};
Arrays.sort(strArr); // String의 Comparable 구현에 의한 정렬
System.out.println("strArr=" + Arrays.toString(strArr));
Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); // 대소문자 상관 없이 정렬
System.out.println("strArr=" + Arrays.toString(strArr));
Arrays.sort(strArr, new Descending()); //역순으로 정렬
System.out.println("strArr=" + Arrays.toString(strArr));
}
}
class Descending implements Comparator {
public int compare(Object o1, Object o2){
if( o1 instanceof Comparable && o2 instanceof Comparable) {
Comparable c1 = (Comparable)o1;
Comparable c2 = (Comparable)o2;
return c1.compareTo(c2) * -1 ; //-1을 곱해서 기본 정렬방식의 역으로 변경
// 또는 c2.compareTo(c1)와 같이 순서를 바꿔도 됨
}
return -1;
}
}
Integer와 Comparable
삼항연산자가 기본사칙연산보다 상대적으로 빠르다 (2~3% 정도)
버블정렬 bubble sort 코드
서로 인접한 두 원소의 대소를 비교하고, 조건에 맞지 않다면 자리를 교환하며 정렬하는 알고리즘
List list = new ArrayLsit(); //다른 컬렉션으로 변경할 때는 이 부분만 고치면 된다.
Iterator it = list.interator();
while(it.hasNext()) { //boolean has Next()
System.out.println(it.next());
}
iterator는 1회용이라 다쓰고나면 다시 얻어와야 한다
Map과 Iterator
Map에는 iterator()가 없음
Keyset(), entrySet(), values()를 호출해야함
Map map = new HashMap();
.
.
.
Iterator it = map.entrySet().iterator();
JPA를 활용하여 연관관계를 맺어줘서 게시글 하나만 삭제해도 관련된 댓글이 다 삭제가 되고, 게시글 하나만 불러도 연관된 댓글이 몽땅 다 삭제되는 것을 구현하는 것에 성공했습니다. JPA는 테이블을 객체처럼 사용한다에서 흰트를 얻어서 객체처럼 넣어주고 값을 불러주고 하는 방법으로 구현했습니다. 복잡한 코드를 작성하지 않더라도 전체 게시글 조회할 때 각 게시글에 연관된 댓글들이 함께 조회가 됩니다. 어제는 중첩 for문을 돌려서 전체 게시글(+댓글) 조회를 했는데 JPA로 for문 필요 없이 간단하게 불러오게 했습니다.
//게시글 전체 조회 USER/ADMIN 상관 없음
public List<PostResponseDto> getPostList() {
List<Post> postList = postRepository.findAllByOrderByModifiedAtDesc();
if(postList.isEmpty()){
throw new NullPointerException("게시글이 존재하지 않습니다.");
}
List<PostResponseDto> postResponseDtoList = new ArrayList<>();
//각 게시물마다 조회해서 넣어줌
for (Post post : postList) {
postResponseDtoList.add(new PostResponseDto(post));
}
return postResponseDtoList;
}
@Transactional(readOnly = true)
//게시글 상세 조회 USER/ADMIN 상관 없음
public PostResponseDto getPost(Long id) {
Post post = postRepository.findById(id).orElseThrow(
() -> new NullPointerException("해당 게시글은 존재하지 않습니다.")
);
// List<CommentResponseDto> commentResponseDtoList = new ArrayList<>();
// for (int i =0; i<post.getCommentLists().size(); i++){
// Comment comment = post.getCommentLists().get(i);
// commentResponseDtoList.add(new CommentResponseDto(comment));
// }
return new PostResponseDto(post);
}
게시글을 불러오면 댓글은 자동으로 따라오기 때문에 댓글 관련해서 작성했던 코드를 지워주었습니다.
JPA 연관관계 설정을 잘 해놓으니 매우 편리하네요!!
결론
JPA 연관관계를 도대체 어떻게, 왜 쓰는지를 해결했습니다. 스프링 첫주차부터 JPA 연관관계 강의를 들었는데 이제사 좀 이해가 되는 것 같습니다. 연관관계를 설정해 놓으면 알아서 데이터가 연관되어서 불러오고 삭제하는 것이 간단해집니다. 연관관계 설정도 조금만 더 연습해보면 잘 할 수 있을 것 같습니다. 시간이 괜찮으면 좋아요와 대댓글 기능도 구현을 해보려 합니다.
public void method1() {
try {
method2();
} catch(ClassNotFoundException e){
//예외 처리 코드
System.out.println("클래스가 존재하지 않습니다.");
}
}
public void method2() throws ClassNotFoundException {
Class claszz = class.forName("java.lang.String2");
}
==> 호출한 곳에서 예외 처리 예시
확인문제
try{} 블록에는 예외가 발생할 수 있는 코드를 작성한다
catch {} 블록은 try {} 블록에서 발생한 예외를 처리하는 블록이다.
try{} 블록에서 return 문을 사용하면 finally {} 블록은 실행되지 않는다. (x)
어제 팀원들이랑 대화하다가 새벽 3시쯤 잠들어서 파워냅 30분했는데 코딩하는 꿈을 꿨습니다...😱 하루종일 코딩만 생각하니 이런 꿈도 꿉니다. 오늘은 주특기 2주차 시작일로 Spring 숙련주차입니다. 강의가 새로 지급되었고 개인과제와 팀과제가 새로 나왔습니다. 다들 월드컵 보러 갈 때 치킨으로 만족하고 강의 듣습니다.🍗🍗🍗
zep
JPA 심화
JPA는 자동으로 Id값을 찾아주지만 (@GeneratedValue 사용) Query는 Select를 사용해 최대값을 넣어서 찾아서 마지막 id값+1해서 넣어줘야 한다
벌써 12월이 되었습니다. 한달이 훌쩍 지나갔네요. 정식으로 부트캠프는 99일이라고 홍보가 되어있지만 사전 스터디 기간까지 합친다면 거진 2달의 기간이 지나갔습니다. 11월에는 자바가 무엇인지 객체지향 프로그램이 무엇인지 처음 배우는 시간이었습니다. 그동한 배우고 구현 해본 것들을 나열하자만 아래와 같습니다.
JWT를 이용해서 Flask python 회원가입, 로그인 기능 구현
자바의 정석 유튜브 동영상 강의 ch 1 ~ 7
프로그래머스 문제 풀이 30개
혼자공부하는 자바 ch 1 ~ 7
깃과 깃허브 사용해서 협업
1주차 미니프로젝트 완성
2주차 알고리즘 test
3주차 Spring 주특기 1주차 강의
객체지향 프로그래밍 과제
게시판 구현 (CRUD 기능 구현: 등록, 조회, 수정, 삭제)
Postman 사용
JPA 기초
HTTP method (PUT, POST, DELETE 등)
API 명세서 작성
API 만들기
생각보다 한 게 많지만 없습니다.
개발자가 되기 위한 단계로 보면 이제 튜토리얼의 튜토리얼을 뗀 수준입니다.
프로그래머의 삶
자바도 그렇고 이제 갓 배우기 시작해서 뭐든 다 새롭고 매일 엄청난 양의 새로운 정보를 습득하다 보니 혼란할 때도 많습니다. 어제 튜터님께 자바 공부를 하고 있다고 말씀드리니까 자바 백엔드 개발자 공부 로드맵을 이야기 해주셨습니다.
interface 인터페이스이름 {
public static final 타입 상수이름 = 값; //상수
public abstract 메서드이름(매개변수목록); //추상메서드
}
//인터페이스의 모든 메소드는 public이고 final이고 abstract 여서 생략 가능
인터페이스의 상속
인터페이스의 조상은 인터페이스만 가능(Object가 최고 조상이 아님)
다중 상속이 가능 (추상메서드는 충돌해도 문제 없음)
interface Fightable extends Movable, Attackable {}
interface Movable {
/** 지정된 위치(x,y)로 이동하는 기능의 메서드 */
void move(int x, int y);
}
interface Attackable {
/** 지정된 대상(u)을 공격하는 기능의 메서드 */
void attack(Unit u);
}
인터페이스의 구현
인터페이스에 정의된 추상 메서드를 완성하는 것
class 클래스이름 implements인터페이스이름 { // 인터페이스에 정의된 추상메서드를 모두 구현해야 한다 }
구현한다는 의미의 키워드 'implements'를 사용함
class Fighter implements Fightable {
public void move(int x, int y) { /*내용 생략 */}
public void attack(Unit u) { /*내용 생략 */} // 몸통 완성
}
//Fighter 클래스는 Fightable 인터페이스를 구현했다.
추상클래스 완성과 동일; 키워드만 다름
일부만 구현하는 경우, 클래스 앞에 abstract를 붙어야 함
인터페이스란?
추상 메서드의 집합
인터페이스의 구현이란?
인터페이스의 추상메서드 몸통{} 만들기(미완성 설계도 완성하기)
추상 클래스와 인터페이스의 공통점은?
추상 메서드를 가지고 있다 (미완성 설계도)
추상 클래스와 인터페이스의 차이점은?
인터페이스는 iv를 가질 수 없다
인터페이스를 이용한 다형성
인터페이스도 구현클래스의 부모
인터페이스 타입 매개변수는 인터페이스 구현한 클래스의 객체만 가능
인터페이스를 메서드를 리턴타입으로 지정할 수 있다
abstract class Unit2 {
int x, y;
abstract void move(int x, int y);
void stop() {
System.out.println("멈춥니다.");
}
}
interface Fightable { //인터페이스의 모든 메서드는 public abstract. 예외 없이
void move (int x, int y); // public abstract가 생략됨
void attack(Fightable f); // public abstract가 생략됨
}
class Fighter extends Unit2 implements Fightable{
//오버라이딩 규칙: 조상(public) 보다 접근제어자가 좁으면 안된다.
public void move (int x, int y) {
System.out.println("["+x+","+y+"]로 이동");
}
public void attack(Fightable f){
System.out.println(f+"를 공격");
}
}
public class FighterTest {
public static void main(String[] args) {
// Fighter f = new Fighter();
Unit2 u = new Fighter(); //Unit2에는 attack()이 없어서 호출불가
Fightable f = new Fighter();
u.move(100, 200);
// u.attack(new Fighter()); //Unit2에는 attack()이 없어서 호출불가
u.stop();
f.move(100, 200);
f.attack(new Fighter());
// f.stop(); //Fightable에는 stop()이 없어서 호출불가
}
}
인터페이스의 장점
두 대상(객체) 간의 '연결, 대화, 소통'을 돕는 '중간 역할'을 한다
GUI - Graphic User Interface
선언(설계, 껍데기)와 구현(알맹이)을 분리시킬수 있게 함
변경에 유리하고 유연한 코드가 됨
인터페이스 덕분에 B가 변경되어도 A는 안바꿀 수 있게 됨 -> 느슨한 결합
의존도가 낮아짐
개발 시간 단축 가능
변경에 유리한 유연한 설계 가능
표준화가 가능
서로 관계없는 클래스들을 관계를 맺어줄 수 있음
다중상속 가능
class A{
public void method(I i) { //인터페이스 I를 구현한 넘들만 들어와라
i.method();
}
}
// B클래스의 선언과 구현을 분
interface I {
public void method();
}
class B implements I{
public void method(){
System.out.println("B클래스의 메서드");
}
}
class C implements I{
public void method(){
System.out.println("C클래스의 메서드");
}
}
public class InterfaceTest {
public static void main(String[] args) {
A a = new A();
a.method(new C()); // A가 B를 사용(의존)
}
}
abstract class Player { //추상 클래스
abstract void play(int pos); //추상 메서드
abstract void stop(); //추상 메서드 (선언부만 있고 구현부{}가 없는 메서드)
}
//추상 클래스는 상속을 통해 완성해야 객체 생성가능
class AudioPlayer extends Player {
@Override
void play(int pos) {
System.out.println(pos+"위치부터 play 합니다");
}
@Override
void stop() {
System.out.println("재생을 멈춥니다.");
}
}
public class PlayerTest {
public static void main(String[] args) {
// Player p = new Player(); // 추상 클래스의 객체를 생성
// AudioPlayer ap = new AudioPlayer();
Player ap = new AudioPlayer(); //다형성
ap.play(100);
ap.stop();
}
}
추상클래스의 작성
- 여러 클래스에 공통적으로 사용될 수 있는 추상클래스를 바로 작성하거나 기존 클래스의 공통 부분을 뽑아서 추상클래스를 만든다
public class Ex7_10 {
public static void main(String[] args) {
// Unit[] group = new Unit[]{new Marine(), new Tank(), new Dropship()};
Unit[] group = new Unit[3];
group[0] = new Marine();
group[1] = new Tank();
group[2] = new Dropship();
for(int i = 0; i < group.length; ++i)
group[i].move(100, 200);
}
}
abstract class Unit {
int x, y;
abstract void move(int x, int y);
void stop() {/*현재 위치에 정지*/}
}
class Marine extends Unit { //보병
void move(int x, int y) {
System.out.println("Marine[x="+x+",y="+y+"]");
}
void stimPack() {/*스팀팩을 사용한다. */}
}
class Tank extends Unit { //탱크
@Override
void move(int x, int y) {
System.out.println("Tank[x="+x+",y="+y+"]");
}
void changeMod() { /*공격모드를 변환한다.*/}
}
class Dropship extends Unit { //탱크
@Override
void move(int x, int y) {
System.out.println("Dropship[x="+x+",y="+y+"]");
}
void change() { /*공격모드를 변환한다.*/}
}