[API]
API: 응용프로그램(일반적인 앱)을 만들기 위한 도구들
API는 절대 모든 API를 공부 할 수 없다. (너무많아서)
API는 필요할때 찾아서 쓰는 것이다. 예전에는 검색해서 썼었지만, 이제는 GPT에게...
대부분의 경우, API의 내부 동작을 이해 할 필요는 없다. 사용에만 관심을 가지는것이 정신적으로 이롭다...
API는 외우는 것이 아닌, 써가면서 익숙해지는 것이다. 저절로 많이 쓰이는 API는 외워지기 때문에.
하지만, 몇몇개의 중요한 API는 동작 구조를 이해할 수록 잘 사용 할 수 있다.
이해가 중요한 API: 자료구조(컬렉션프레임워크), 네트워크 관련. ..., 스프링프레임워크
또한, 공식 문서를 읽어보는것도 좋긴 한데, 사실 GPT가 좀 더 낫다. 공식문서에는 패키지, 상속과 같은 것들이 나온다. 어느정도의 내용들은 IDE에서 API에 마우스오버를 하면 나오긴 한다.
API의 타입에 따라서 그 타입에 맞는 형식의 API들을 계속 이어붙일 수 있다. 작성을 하다보면 자동완성 부분에 취소선이 있는 경우는 지금 당장은 문제가 없는데, 없어질 수도 있는것(설계에 문제가 있거나 하면 뜸) 마우스 오버 해보면 변경된 것이 뜰 때도 있다. 가능하면 쓰지 않거나 주의해야 한다.
[String 관련 API]
subString: 문자열의 특정 구간을 잘라서 반환하는 API. 매개변수가 1개인 경우, 2개인 경우의 생성자를 만들어 두었으며, int startIndex, int endString으로 이름을 매겨두어서 검색을 하지 않고도 사용법을 알 수 있게 해두었다. 하지만, int 타입이기 때문에 문자열을 넣을 수 없는데, 이때 사용하는게 indexOf이다.
indexOf: 문자열에서 매개변수로 받아온 문자열이 존재하는 앞에서부터 위치를 찾아서 정수로 반환. 뒤에서부터 찾고 싶을때는 lastIndexOf를 쓴다. 그렇게 받은 정수 위치값을 subString의 매개변수로 전달해서 원하는 문자열을 받아온다.
charAt: 문자열에서 특정 위치의 문자 하나를 꺼낸다. 문자 하나만을 검사할때
contact: 문자열을 이어붙이는 API. 사실 C언어쪽에서 자주 쓰지 자바는 안씀. + 연산자가 있어서.
contains: 문자열에 접근해서, 매개변수로 받은 문자열과 같은 문자열이 포함 되어 있는지 판단하는 API. 보통 검색 기능에 많이 쓰임
trim: 문자열의 앞뒤 공백을 제거한 새 문자열을 반환하는 API. 검색 기능을 구현할때, 사용자가 실수로 공백을 넣을 수 있기 때문에, 이러한 노이즈들을 제거할때 쓰인다.
length: 문자열의 길이를 알려주는 API. 자주 쓰인다.
replace: 첫번째 매개변수를 두번째 매개변수로 바꿈
split: 문자열을 분리하는 것. 분리하는것이기 때문에 리턴타입이 배열이다. 그렇기 때문에 사용할때 선언한 변수는 배열이어야 한다.
format: c언어 처럼 출력가능. printf랑 같은 느낌?
스태틱 API는 거의 쓸 일이 없다. 쓴다면 join 정도?
불변객체: 대다수의 자바 라이브러리들은 불면 객체. 물론 가변객체도 있지만 값을 다루는건 보통 불변. 직접적으로 변경이 물가하며, 변경 시 새로운 인스턴스를 생성해더되돌려준다.
Object: 최 상위 객체로, 모든 값을 다 담을 수 있기 때문에, 어떤 값이든 담아야 할때 사용. 다형성, 오버라이딩이 중요하다.
박싱: 값을 그대로 보내는게 아니라 중간에 포장해서 보내는거
언박싱: 포장된 값을 풀어서 가져오는거
[p1]
package p1;
public class App {
public static void main(String[] args) {
int value = 10;
double result = Math.sqrt(value);
System.out.println(value + " 의 루트 값: " +result);
}
}
[p2]
package p2;
public class App {
public static void main(String[] args) {
// String
String fileName = "C:/aaaa/bbbb/cccc/dddd.jpg";
int dotIndex = fileName.lastIndexOf(".");
String ext = fileName.substring(dotIndex);
System.out.println("확장자: " + ext);
ext = fileName.substring(fileName.lastIndexOf("."));
// 이거는 위에 코드를 한줄로 쓴것.
System.out.println("확장자: " + ext);
String a1 = "안녕하세요. 만나서 반갑습니다!";
if(a1.contains("헬로")) { // a1에 접근해서 "헬로"가 포함 되어 있는지 확인
System.out.println("포함되어 있음.");
} else {
System.out.println("포함되어 있지 않음.");
}
String a2 = "안녕 반가워 aaa bbb";
if(a2.toUpperCase().contains(" AA ".trim())) {
// 모두 대문자로 바꿔서 검색하고, 입력한 값의 노이즈도 제거하는 것.
System.out.println("포함 되어 있다.");
} else {
System.out.println("포함되어 있지 않다.");
}
String a3 = " 안녕하세요.";
System.out.println(a3.trim());
// 이거는 a3에 공백을 제거해서 출력한 것이기 때문에,
// a3에는 공백이 그대로 남아있다. println은 void라서.
System.out.println(a3); // 이런걸 불변 객체라고 한다.
StudentDto s1 = new StudentDto("철수");
// s1.setName("민수"); // 가변 객체 사용하는거.
// s1.setName("철수");
s1 = s1.changeName("민수");
s1.changeName("...");
int a4 = 2;
int a5 = 5;
int result = a4 * a5;
String a6 = String.format("%d X %d = %d", 3, 4, 12);
}
}
/* 가변 객체
class StudentDto {
private String name;
public void setName(String name) {
this.name = name;
}
// ...
} */
// 불변 객체
class StudentDto {
private final String name;
public StudentDto(String name) {
this.name = name;
}
public StudentDto changeName(String name) {
// 새로 만드는게 아니라 값을 바꾸는거니까 이름에 set 대신에 change로
StudentDto newStudentDto = new StudentDto(name);
return newStudentDto;
}
public String print() {
return name;
}
}
[p3]
package p3;
public class App {
public static void main(String[] args) {
//
long time = System.currentTimeMillis();
// String text = "";
// for(itn i = 0; i < 100; i++) {
// text = text + "야호";
// ㄴ text + "야호" 에 해당하는 인스턴스를 새로 생성함.
// // 새로 생성된 메모리 주소값을 다시 text에 넣는 것.
// // 인스턴스 생성은 꽤나 비용적인 측면에서 좋지 않음
// }
// String은 불변객체이기 때문에 값 변환시 새로운 인스턴스를 생성한다.
StringBuffer sb = new StringBuffer("시작");
for(int i = 0; i < 1000000; i++) {
sb.append("야호");
}
System.out.println(System.currentTimeMillis() - time + "ms");
// System.out.println(text);
}
}
[p4]
package p4;
public class App {
public static void main(String[] args) {
// Object
/* AAA rr = new AAA();
Object qqq = 1;
qqq = "asdasd";
// 모든 클래스의 부모(최상위 개체)는 Object이기 때문에
// Object는 모든 값을 받을 수 있다. (다형성)
System.out.println(rr);
System.out.println(qqq); */
StudentDto s1 = new StudentDto("민수", 21, 70);
StudentDto s2 = new StudentDto("민수", 21, 70);
// "asd".equals(123);
// ㄴ 이거 되긴 하는데, 무조건 false. 다른 타입이라.
if(s1.equals(s2)) {
// 원래 equals는 String에 속한 것이 아니라, Object에 있는것.
// Object에 있는 equals는 주소값을 비교한다. 그래서 if(s1 == s2) 랑 같음.
// 즉, String의 equals는 Object를 오버라이딩으로 재정의한것
}
if(s1.equals(s2)) {
System.out.println("같다");
} else {
System.out.println("다르다");
}
}
}
class StudentDto {
String name;
int age;
int score;
public StudentDto(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
// 오버라이드 할때는 관례적으로 써야 함.
// 혹시라도 오타가 있으면 아예 다른 이름의 메서드를 만드는거라
public boolean equals(Object x) {
// 같다의 기준을 정의 할 수 있다.
if(!(x instanceof StudentDto)) {
return false;
}
StudentDto other = (StudentDto)x;
if(this.age == other.age) {
return true;
}
return true;
}
}
class AAA {
// java는 무조건 무언가를 상속 받아야 함.
// 그렇기 때문에 extends Object가 생략 되어 있는 것
int a = 10;
int b = 20;
String names = "민수";
public String toString() {
return "[a= " + a + ", b= " + b + ", name" + names + "]";
}
}
class BBB extends AAA {
}
[5]
package p5;
public class App {
public static void main(String[] args) {
// 문법을 벗어나는 클래스들: String, 각종 wrapper 클래스
// String도 클래스. 원래는 new를 써야 한다.
// +도 원래는 인스턴스+인스턴스(참조변수)가 안되는데 String는 할 수 있게 해줬다
// wrapper 클래스: 각 기본 타입에 대응되는 클래스
// byte = Byte (대문자가 클래스)
// short = Short
// int = Integer
// long = Long
// ...
// char = Character
Integer a = 3; // 박싱 발생
// 타입 미스매치긴 하다. Integer는 참조타입이고 3는 정수 타입이기 때문.
// 그래서 문법을 벗어났다고 하는거.
int b = a; // 언박싱 발생
// int에 a를 넣다니.. 문법 씨게 벗어났다. 좀 쉽게쉽게 쓰라는 의미에서 가능한것.
int c1 = 50;
Integer c2 = 50;
// int가 아니라 Integer인 이유는 null값 때문.
// Integer는 참조변수라 null을 받을 수 있다.
Integer c3 = null;
// 결론: wrapper클래스로는 최대한 연산을 자제하라.
// 인스턴스의 생성, 소멸로 인해 어마어마한 오버헤드가 발생한다.
Integer sum = 0;
for(Integer i = 0; i < 10; i++) {
sum += 1;
} // 정말 정신나간 코드.
int b1 = Integer.parseInt("333");
System.out.println(b + b1);
c3 = 10;
System.out.println(c1 + c2 + c3);
}
}
[p6]
package p6;
import java.util.Date;
public class P6 {
public static void main(String[] args) {
// 데이터의 형태: 숫자, 문자, 날짜
Date date = new Date(); // 현재 시간.
System.out.println(date);
System.out.println(date.getTime());
// 1970년 1월 1일 00:00:00 (UTC)부터 현재까지 흐른 시간을 밀리초(ms)로 반환
System.out.println(date.getTime()/1000/60/60/24/365);
// 그때부처 몇년이 지났는지 구하는거
System.out.println(date);
// System.out.println(date.getMonth());
}
}
[p7]
package p7;
import java.util.Date;
import java.text.SimpleDateFormat;
public class App {
public static void main(String[] args) throws Exception {
// ㄴ 이 메서드 안에서 발생할 수 있는 예외를 호출한 쪽에 떠넘기는 무책임한 코드긴 하다
// 숫자 <-> 문자
// - 숫자 -> 문자
int a1 = 10;
String a2 = a1 + "";
String a3 = String.valueOf(a1);
String a4 = Integer.toString(a1);
// - 문자 -> 숫자
String b1 = "123";
int b2 = Integer.parseInt(b1);
// 날짜 <-> 숫자
// - 날짜 -> 숫자
Date c1 = new Date();
long c2 = c1.getTime();
// - 숫자 -> 날짜
long d1 = 2903801283313L;
Date d2 = new Date(d1);
// 날짜 <-> 문자
// - 문자 -> 날짜
String e1 = "1987/07/21";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/mm/dd");
Date e2 = sdf.parse(e1);
// - 날짜 -> 문자 (예쁘게 출력)
Date f1= new Date();
System.out.println(f1);
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy.mm.dd");
// .을 붙이는게 웹에서 가장 이쁘게 나옴
String f2 = sdf2.format(f1);
System.out.println(f2);
System.out.println(a2 + a3 + a4 + b2 + c1 + c2 + d2 + e2);
}
}
[p8]
package p8;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class App {
public static void main(String[] args) {
LocalDateTime aaa = LocalDateTime.now();
System.out.println(aaa);;
LocalDate bbb = LocalDate.of(2020, 10, 13);
System.out.println(bbb);
}
}