Post

JAVA

특징

  • 플랫폼 독립적: 운영체제 따라 코드를 재 작성하지 않아도 됨
  • 객체 지향적: 절차 지향적 언어에 비해 생산성과 보안성이 높음

실행 과정

자바 소스코드(.java) —(자바 컴파일러)—> 바이트코드(.class) —(Java Virtual Machine)—> 실행

String

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// %02d 포맷 지정자는 숫자가 한 자릿수일 경우 앞에 0을 추가하여 총 두 자리 숫자로 표시
String s; 
for(int i = 1; i < 10; i++){ //구구단 출력
    for(int j = 1; j < 10; j++){
        s = String.format("%02d x %02d = %02d ", j, i, i*j);
        System.out.print(s);
    }
    System.out.println();
}

String s1 = "Hi"; 
String s2 = "Hi";
String s3 = new String("Hi");
System.out.println(s1.equals(s2)); //true
System.out.println(s1 == s3); //false

s1 == s2가 true를 반환하는 이유는, s1과 s2가 둘 다 문자열 리터럴 “Hi”에 의해 초기화되었기 때문입니다. 자바에서는 같은 문자열 리터럴에 대해 하나의 String 객체를 재사용합니다. 따라서, s1과 s2는 동일한 메모리 위치를 가리키게 되고, == 연산자는 true를 반환합니다.

s1 == s3가 false를 반환하는 이유는, s3가 new String(“Hi”)를 사용하여 명시적으로 새로운 String 객체를 생성했기 때문입니다. 이 경우, s3는 s1이나 s2와는 다른 메모리 위치를 가리키게 됩니다. 그래서, == 연산자는 두 참조가 서로 다른 객체를 가리키고 있다고 판단하고 false를 반환합니다.

1
2
3
4
5
6
7
8
9
// - StringBuffer : 문자열을 자주 추가하거나 변경할 때 사용
// 값이 변경되어도 객체가 새로 생성되는 일이 없음
// String은 값에 변화가 생길 때마다 객체가 새로 생성 됨
StringBuffer sb = new StringBuffer("Hello World");
// method : append, insert substring

//array 선언
int[] array = {1,2,3,4};
String[] str = new String[3];
1
2
3
4
5
//list
ArrayList list = new ArrayList();
list.add(1);
// method : add, get, size, remove, clear, sort, contains
list.sort(Comparator.naturalOrder()); //오름차순 정렬

ArrayList에는 두 가지 형태의 remove 메서드가 있습니다

  • remove(int index) : 인덱스에 위치한 요소를 제거하고, 제거한 값을 반환합니다.
  • remove(Object o) : 매개변수로 받은 객체와 일치하는 첫 번째 요소를 제거합니다. 객체가 리스트 내에 있을 때 제거하고 true를 반환하며, 없을 경우 false를 반환합니다.
1
2
3
4
5
6
7
8
//Map : key, value 쌍으로 이루어짐. key 값을 통해서 접근(get("key"))
HashMap map = new HashMap();
map.put("product", "kiwi");
//method : put, get, size, remove, containsKey

//Generics : 자료형을 명시적으로 지정, 안전성 증가, 형변환 자동
ArrayList<String> list = new ArrayList<String>();
HashMap<String, String> map = new HashMap<String, String>();

형변환

1
2
int num = Integer.parseInt("123");
String str = Integer.toString(123);

삼항 연산자

연산에 사용되는 항이 세 개 왼쪽에 식이 맞았을 때 사용할 값 입력 ex) (3 > 1) ? 1 : 0

2의 보수

2의 보수는 주로 음수를 표현하는 데 사용

2진수 3의 2의 보수를 구하는 방법

  1. 주어진 수의 이진수 표현을 찾습니다: 3 -> 11
  2. 이진수의 모든 비트를 반전시킵니다 (0은 1로, 1은 0으로): 11 -> 00
  3. 반전된 수에 1을 더합니다: 00 + 1 = 01

비트 논리 연산자

&(AND), |(OR), ^(XOR), ~(NOT) « 연산자 : 비트를 왼쪽으로 이동, 곱하기 2 효과

연산자 : 비트를 오른쪽으로 이동, 나누기 2 효과(기존의 부호비트로 앞을 채움 )

연산자 : 부호비트 상관 없이 0으로 채움

오버로딩(Overloading)

  • 한 클래스 내에서 같은 이름의 메소드를 여러 개 정의
  • 매개변수의 개수 또는 타입이 달라야 함(리턴타입 차이로는 오버로딩 x)

접근제어자

  • public: 어디서든 접근 가능
  • private: 해당 클래스에서만 접근 가능
  • (defalut): 해당 패키지 내에서만 접근 가능
  • protected: 해당 패키지 및 상속 받은 클래스에서 접근 가능

Static과 final

static

  • 클래스 변수와 메소드: static 키워드를 사용하면 해당 변수나 메소드는 클래스에 속하게 됩니다. 즉, 특정 인스턴스가 아닌 클래스 자체에 속합니다.
    1
    2
    3
    4
    5
    6
    7
    
    public class Example {
        static int staticVariable = 10;
          
        static void staticMethod() {
            System.out.println("This is a static method.");
        }
    }
    
    • 클래스 변수: static 변수는 모든 인스턴스가 공유합니다. 즉, 하나의 클래스에 속하는 모든 객체가 동일한 static 변수를 공유합니다.
    • 클래스 메소드: static 메소드는 객체의 상태와 무관하게 호출할 수 있습니다. 객체 인스턴스를 생성하지 않고도 호출할 수 있습니다.

final

  • 상수 변수: final 키워드를 사용하여 변수를 선언하면 그 변수는 한 번 초기화된 후 값을 변경할 수 없습니다.
    1
    2
    3
    
    public class Example {
        final int constantVariable = 100;
    }
    
    • 상수 변수: final 변수는 한 번 값이 설정되면 더 이상 값을 변경할 수 없습니다. 보통 상수로 사용됩니다.
  • 메소드: final 메소드는 서브클래스에서 오버라이드할 수 없습니다.
    1
    2
    3
    4
    5
    
    public class Example {
        final void finalMethod() {
            System.out.println("This method cannot be overridden.");
        }
    }
    
  • 클래스: final 클래스는 다른 클래스가 상속할 수 없습니다.
    1
    2
    3
    
    public final class Example {
        // This class cannot be subclassed.
    }
    

요약

  • static: 클래스 변수 및 메소드, 클래스 수준에서 접근 가능.
  • final: 상수 변수, 메소드 오버라이딩 방지, 클래스 상속 방지.

상속(Inheritance)

  • 부모 클래스의 필드와 메소드가 상속됨
  • 오버라이딩(Overrifing) : 부모 클래스의 메소드를 자식 클래스에서 재정의(메소드 선언부는 부모 클래스의 선언부와 동일해야 한다.)
    1
    2
    3
    4
    5
    6
    
    class 자식클래스명 extends 부모클래스명 {
    //필드;;
    //메소드;;
    super(); //부모 클래스의 생성자 호출
    //super.부모필드;
    }
    

다형성(Polymorphism)

  • 한 객체가 여러 가지 타입을 가질 수 있는 것
  • 부모 클래스 타입의 참조 변수로 자식클래스 인스턴스 참조
1
2
3
4
5
6
7
8
9
class Person{}
class Student extends Person{}

Person p1 = new Student();   // 다형성, 업캐스팅
//이 경우 자식 클래스에서만 정의한 메소드 사용 불가

Student s1 = (Student)p1; //다운캐스팅

//Student s1 = new Person(); // 불가

추상화

추상화는 복잡한 시스템을 단순화하여 필요한 부분만을 클래스로 표현하는 작업. 이는 속성(attribute)과 행동(method)을 통해 실현.

추상 클래스(Abstract Class)

  • 정의: 하나 이상의 추상 메소드를 포함하는 클래스.
  • 추상 메소드(Abstract Method):
    • 자식 클래스에서 반드시 오버라이딩해야 하는 메소드
    • 메소드 선언만 있고, 구현 내용은 없다.
  • 목적: 반드시 구현해야 하는 부분을 명시적으로 표현.
  • 특징: 추상 클래스 자체로는 객체를 생성할 수 없다.
1
2
3
abstract class 클래스명 {
    abstract void print();
}

예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
abstract class Animal {
    // 추상 메소드
    abstract void makeSound();

    // 일반 메소드
    void breathe() {
        System.out.println("Breathing");
    }
}

class Dog extends Animal {
    // 추상 메소드를 구현
    @Override
    void makeSound() {
        System.out.println("Bark");
    }
}

public class Main {
    public static void main(String[] args) {
        // Animal animal = new Animal(); // 에러: 추상 클래스는 인스턴스화할 수 없음
        Animal dog = new Dog();
        dog.makeSound(); // 출력: Bark
        dog.breathe(); // 출력: Breathing
    }
}

인터페이스

  • 다중 상속처럼 사용할 수 있는 기능
  • 추상 메소드와 상수만으로 이루어짐
1
2
3
4
5
6
7
8
9
10
접근제어자 interface 인터페이스명 {
    public static final 타입 상수이름 = ;  //값 변경 불가
    public abstract 반환타입 메소드이름(매개변수);
}

//상속과 인터페이스 동시 사용
class 클래스B extends 클래스A implements 인터페이스명{

}

내부 클래스(Inner Class)

  • 인스턴스 클래스 : 외부 클래스의 모든 인스턴스 변수 및 메소드에 접근
  • 정적 클래스 : 외부 클래스의 정적 멤버에만 접근 가능
  • 지역 클래스 : 메서드 내부에 정의
  • 익명 클래스 : 선언과 동시에 객체 생성, 일회용
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    class Outer {
    
      class Inner {
          // 내부에서 외부 클래스의 모든 멤버(인스턴스 멤버 포함) 접근 가능
      }
    
      Anony a1 = new Anony(){
          //익명 클래스
      }
    }
    

입출력

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Scanner sc = new Scanner(System.in);
System.out.print("입력: ");
System.out.println(sc.nextLine());
sc.close();

//출력
System.out.printf("%d\n", 10); //정수
System.out.printf("%o\n", 10); //8진수
System.out.printf("%x\n", 10); //16진수

System.out.printf("%f\n", 5.2f); //소수점
System.out.printf("%.2f\n", 1.126123f); //두번째 자리까지 반올림해서 출력
         
System.out.printf("%c\n", 'A');  //문자
System.out.printf("%s\n", "안녕하세요"); //문자열

System.out.printf("%5d\n", 123);   //5개 공간을 차지
System.out.printf("%-5d\n", 1234); //왼쪽에 붙음

예외 처리(Exception Handling)

  • throw : 예외를 발생 시킴
  • throws : 예외를 전가 시킴(메소드 안에서 처리x) ```java class NotTenException extends RuntimeException {}

if (ten != 10) { throw new NotTenException(); // NotTenException 예외를 발생시킴 }

public static boolean checkTenWithThrows(int ten) throws NotTenException {// 메서드 선언에 throws를 사용하여 안에서 처리하지 않고 예외를 전달 if (ten != 10) { throw new NotTenException(); } return true; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
### 컬렉션 프레임워크(Collection Framework)
- 자료 구조 및 알고리즘을 구조화한 것

1. List 인터페이스
   - 순서가 있는 데이터의 집합
   - 데이터 중복 허용
   - ArrayList, LinkedList, Vector

2. Set 인터페이스
   - 순서가 없는 데이터의 집합
   - 데이터의 중복 허용 하지 않음
   - HashSet, TreeSet(add 할때, 자동정렬됨)
  
3. Map 인터페이스
   - 키와 값의 쌍의 집합
   - 순서를 유지하지 않음
   - HashMap, TreeMap
  
```java
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("Apple");
arrayList.add("Banana");
System.out.println(arrayList.get(0));  // 출력: Apple

LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("Carrot");
linkedList.addFirst("Beetroot");
System.out.println(linkedList.getFirst());  // 출력: Beetroot

Vector<Integer> vector = new Vector<>();
vector.add(5);
vector.add(10);
System.out.println(vector.get(1));  // 출력: 10

HashSet<String> hashSet = new HashSet<>();
hashSet.add("Dog");
hashSet.add("Cat");
System.out.println(hashSet.contains("Cat"));  // 출력: true

TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(22);
treeSet.add(15);
System.out.println(treeSet.first());  // 출력: 15

람다 표현식(Lambda Expression)

  • 메소드 대신 하나의 식으로 표현
  • 익명 함수(Anonymous function) 또는 일회용 함수라고도 함
    1
    
    (int x, int y) -> { return x + y; }
    

Stream

  • 배열, 컬렉션 등의 데이터를 하나씩 참조, 처리하는 기능
  • for문의 사용을 줄일 수 있음
  • Stream 생성, 중개 연산, 최종 연산 ```java int[] arr = new int[]{1,2,3}; Stream stream = Arrays.stream(arr); //배열의 경우

ArrayList list = new ArrayList(Arrays.asList(1,2,3)); Stream stream = list.stream(); //컬렉션의 경우

stream.forEach(System.out::println);//쉽게 하나씩 참조하여 출력가능

//중개연산 IntStream intSt = IntStream.range(1,10).filter(n->n%2==0); //필터링 IntStream intSt = IntStream.range(1,10).map(n->n+1); //매핑

//최종연산 int sum = IntStream.range(1,10).sum(); int max = IntStream.range(1,10).max().getAsInt(); ```

This post is licensed under CC BY 4.0 by the author.