말랑한 하루
Java 본문
Java
[ 입출력 ]
◎ Scanner
Scanner sc = new Scanner(System.in);
sc.next(); // word
sc.nextInt(); // num
sc.nextLine(); // sentense
sc.hasNext(); // infinity loof, yet closed
// Scanner 응용
Scanner sc = new Scanner(System.in);
int ary[];
ary = new int[sc.nextInt()];
◎ BufferedReader
Scanner와 중복사용하면 안됨니다!!!
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String s = bf.ReadLine(); // string
//한라인씩 계속해서 받아내는 식
int i = Integer.parseInt(bf.readLine()); // int
StringTokenizer st = new StringTokenizer(s); // string 가공
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
String array[] = s.split(" ") // 공백단위구분
◎ BufferedWriter + StringBuilder
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringBuilder sb = new StringBuilder();
sb.append(centense);
bw.write(sb.toString());
bw.flush();
bw.close();
◎ System.out
System.out.print // 기본출력
System.out.println // 줄바꿈출력
System.out.printf // 연산가능출력
[ Array / 배열 ]
C++에서 쓰던 함수와는 달랏기에 정리하고 가자
array.length // 배열 길이
● String → Char Array 변환
◎ split(), toCharArray()
String value = "input String Value";
String array[] = value.split(" ");
String value = "inputStringValue";
Char array[] = value.toCharArray();
● BOJ, SWEA에서 활용하기
◎ 숫자 그대로 입력받기 / 공백 구분해서 변수넣기 / String문자열 2차원 배열로 변환하기
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//숫자 그대로 입력받기
int TC = Integer.parseInt(br.readLine());
//공백있는 숫자 구분하여 변수에 넣기
String b[] = br.readLine().split(" ");
int H = Integer.parseInt(b[0]);
int W = Integer.parseInt(b[1]);
//String문자열을 2차원배열로 변환하기
map = new char[H][W];
for(int i=0;i<H;i++) {
map[i] = br.readLine().toCharArray();
[ 정렬 ]
◎ Comparable : 오름차순 사전순정렬
// Object Array
// Primitive Array = Dual Pivot QuickSort(QuickSort+Insertion Sort)
// Primitive Array = base of type Sort
Arrays.sort();
// List Collection
// ArrayList, LinkedList, Vector, etc..
// Inpartition : usihng Arrays.sort();
Collections.sort();
// this < parameter : return -1;
// this == parameter : return 0;
// this > parameter : return 1;
// if return 1, parameter will be changed
class Point implements Comparable<Point> {
int x, y;
// ex) x는 증가하고 y는 감소하는 정렬의경우
@Override
public int compareTo(Point p) {
if (this.x > p.x) return 1;
else if (this.x == p.x)
if (this.y < p.y) return 1;
return -1;
}
// ex) x는 증가하고 y도 증가하는 정렬의경우 :: 기본형
@Override
public int compareTo(Point p) {
if (this.x > p.x) return 1;
else if (this.x == p.x)
if (this.y > p.y) return 1;
return -1;
}
}
//리스트 생성부터 정렬까지
ArrayList<Point> list = new ArrayList<>();
list.add(new Point(x, y));
Collections.sort(list);
◎ Comparator : 사용자지정 정렬, ex) 내림차순
class MyComparator implements Comparator<Point> {
@Override
public int compare(Point p1, Point p2) {
if (p1.x > p2.x) return 1;
else if (p1.x == p2.x)
if (p1.y < p2.y) return 1;
return -1;
}
//리스트 생성부터 정렬까지 2가지방법 (기본, 익명클래스)
Arraylist<Point> list = new ArrayList<>();
list.add(new Point(x, y));
MyComparator comp = new MyComparator();
Collections.sort(list, comp);
//or
Arraylist<Point> list = new ArrayList<>();
list.add(new Point(x, y));
Collections.sort(list, MyComparator);
[ String / 문자 ]
● 특정 인덱스 문자변환
◎ String
stringValue.substring(first, middle)+'changeValue'+stringValue.substring(middle+1,last)
◎ StringBuilder
stringbuilderValue.setCharAt(place, 'changeValue');
◎ StringBuilder → String
String stringValue = ""+stringbuilderValue;
● 문자 연결하기
◎ concat (String)
연결 요소인 value가 null이면 불가능함
String value = "string";
value.concat("value");
◎ append (StringBuilder)
StringBuilder sb = new StringBuilder("string");
sb.append("value")
[ Value / 숫자 ]
● 천 단위 숫자 콤마찍기
◎ DecimalFormat
DecimalFormat df = new DecimalFormat("###,###");
[ 문자 ↔ 숫자 ]
● 숫자 → 문자
◎ 기본
String.valueOf(value); Integer.toString(value); ""+i;
◎ 진수변환 (2, 8, 16, typeValue)
Integer.toBinaryString(value);
Integer.toOctalString(value);
Integer.toHexString(value);
● 문자 → 숫자
◎ 기본
Integer.parseInt(value);
◎ 진수변환 (2, 8, 16, typeValue) typeValue : 사용자지정 (ex: 3, 9)
Integer.parseInt(value, 2);
Integer.parseInt(value, 8);
nteger.parseInt(value, 16);
Integer.parseInt(value, typeValue);
Integer.valueOf(value, typeValue);
[ Math / 수학 ]
C++의 Math Container와 동일하되, 사용시 Math클래스를통해 함수들이 불러와 진다는것을 까먹지말자
● ceil, floor
Math.ceil(value); // 올림 : 크거나 같은 가장작은 정수 값
Math.floor(value); // 내림 : 작거나 같은 가장 큰 정수 값
● log
Java의 Math의 log는 C++와달리 무조건 log10이기때문에, log2를 사용하기위해선 log의 특성을 이용해야한다
Math.log(value) // log10
Math.log(value)/Math.log(base) // logbase(value)
ex) Math.log(25)/Math.log(2) = log2(25)
따로 함수를 만드는것도 하나의 방법 :: SegmentTree에 사용하기위해 Int로 설정, 보통은 double
static int baseLog(int value, int base) {
return (int)(Math.log(value)/Math.log(base));
}
[ Pair / 페어 ]
Java에는 C++처럼 Pair가 존재하지않으니 다음과같이 사용해야함. C의 Struct만든다는 생각이면 됨
JavaFx에 Pair가 존재한다는데, 구현하기 쉬우니 구현해서 쓰자
class Pair {
type value_name;
type value_name;
public Pair(type value_name, type value_name) {
this.value_name = value_name;
this.value_name = value_name;
}
}
[ Collections ]
● Set Collections
◎ HashSet
저장공간을 늘릴때 2배씩 늘리기때문에 초기용량을 지정해주는것이 가장 현명함
HashSet<Integer> s = new HashSet<integer>(); // 기본선언
HashSet<Integer> s = new HashSet<>(); // parameter생략
HashSet<Integer> s = new HashSet<integer>(s); // 기존 HashSet복사
HashSet<Integer> s = new HashSet<integer>(num); // 초기용량 capacity 설정
HashSet<Integer> s = new HashSet<integer>(num, float); // capacity, load factor 설정
HashSet<Integer> s = new HashSet<integer>(Array.asList(num, num, num)); // 초기값지정
s.add(value); // 추가
s.remove(value); // 삭제
s.clear(); // 초기화
s.size(); // 크기
s.contains(value) // 요소찾기
// 요소검색
Iterator iter = set.iterator();
while(iter.hasNext()) {
iter.next();
}
◎ LinkedHashSet
HashSet에서 추가할 때, 순서를 기억하고 싶은경우 사용
LinkedHashSet<type> lh = new LinkedHashSet<type>(); // 기본선언
LinkedHashSet<Integer> lh = new LinkedHashSet<>(); // parameter생략
LinkedHashSet<Integer> lh = new LinkedHashSet<integer>(s); // 기존 HashSet복사
LinkedHashSet<Integer> lh = new LinkedHashSet<integer>(num); // 초기용량 capacity 설정
LinkedHashSet<Integer> lh = new LinkedHashSet<integer>(num, float); // capacity, load factor 설정
LinkedHashSet<Integer> lh = new LinkedHashSet<integer>(Array.asList(num, num, num)); // 초기값지정
lh.add(value); // 추가
lh.remove(value); // 삭제
lh.clear(); // 초기화
lh.size(); // 크기
lh.contains(value) // 요소찾기
// 요소검색
Iterator iter = lh.iterator();
while(iter.hasNext()) {
iter.next();
}
◎ TreeSet : Red-Black Tree
BinaryTree중 성능을 향상시킨 Red-Black Tree로 구현되었고, 트리가 한쪽으로 치우치지 않게 균형을맞춤
TreeSet<Integer> s = new TreeSet<Integer>(); // 기본선언
TreeSet<Integer> s = new TreeSet<>(); // parameter 생략
TreeSet<Integer> s = new TreeSet<Integer>(s); // 기존 TreeSet 복사
TreeSet<Integer> s = new TreeSet<Integer>(Arrays.asList(num, num, num)); // 초기값지정
s.add(value);
s.remove(value);
s.clear();
s.size();
s.first();
s.last();
s.higher(value);// value보다 큰 값중 최소값, nonexsitent = null;
s.lower(value); // value보다 작은 값중 최대값, nonexsitent = null;
// 요소검색
Iterator iter = s.iterator();
while(iter.hasNext()) {
iter.next();
}
HashSet 과 LinkedHashSet 등 Set Collection에서는
add()가 중복성을 판단해, 리턴값이 true, false이다.
HashSet 과 LinkedHashSet 등 Set Collection에서는
add()가 중복성을 판단해, 리턴값이 true, false이다.
● List Collections
◎ LinkedList
LinkedList list = new LinkedList(); // type 생략
LinkedList<Class> class = new LinkedList<Class>(); // 해당 Class객체만 사용가능
LinkedList<Integer> list = new LinkedList<Integer>(); // 해당 type만 사용가능
LinkedList<Integer> list = new LinkedList<>(); // parameter 생략
LinkedList<Integer> list = new LinkedList<Integer>(Arrays.asList(num, num, num));// 생성시 값 추가
list.addFirst(value); // 가장 맨앞에 value추가
list.addLast(value); // 가장맨뒤에 value추가
list.add(value); // value 추가
// 가장많이사용하는방법
list.add(index, value); //index뒤에 value추가
// Class객체 List추가방법
Class Class{
string name;
int age;
}
Class c = new Class(name, age);
class.add(c);
class.add(new Class(name, age));
list.removeFirst(); // 가장 맨 앞의 node제거
list.removeLast(); // 가장 맨 뒤의 node제거
list.remove(); // 첫번째 index제거
list.remove(value); // index of value제거
list.clear(); // 초기화
list.size(); // 크기
// 요소구하기
for(Integer i : list)
Iterator<Integer> iter = list.iterator();
while(iter.hasNext()) {
iter.next();
}
list.get(value) // value of index return
list.contains(value); // value가 존재하는지 검색, nonexistent = null
list.indexOf(value); // value가 존재하는 index return
first_list.addAll(second_list);
◎ ArrayList
ArrayList list = new ArrayList(); // nontype 선언
ArrayList<Class> class = new ArrayList<Class>(); // Class객체만 사용가능
ArrayList<Integer> list = new ArrayList<Integer>(); // Int type만 사용가능
ArrayList<Integer> list = new ArrayList<>(); // parameter 생략
ArrayList<Integer> list = new ArrayList<Integer>(value); // 초기용량(capacity) 설정
ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(num, num, num)); // 생성시 값 추가
list.add(value);
list.add(null);
list.add(index, value);
// Class객체 List추가방법
Class Class{
string name;
int age;
}
Class c = new Class(name, age);
class.add(c);
class.add(new Class(name, age));
list.remove(value);
list.clear();
list.size();
// 요소구하기
for(Integer i : list)
Iterator<Integer> iter = list.iterator();
while(iter.hasNext()) {
iter.next();
}
list.get(value); // value of index return
list.contains(value); // value가 존재하는지 검색, nonexistent = null
list.indexOf(value); // value가 존재하는 index return
first_list.addAll(second_list);
◎ Vector
멀티스레드 환경에서 안전하게 객체를 추가, 삭제할 수 있음.
Vector는 스레드가 1개라도 항상 동기화되어 ArrayList보다 성능이 떨어지기때문에 가급적 ArrayList쓰기
Vector v = new Vector(); // nontype 선언
Vector<Class> vc = new Vector<Class>(); // Class객체만 사용가능
Vector<Integer> v = new Vector<Integer>(); // Int type만 사용가능
Vector<Integer> v = new Vector<>(); // parameter 생략
Vector<Integer> v = new Vector<Integer>(value); // 초기용량(capacity) 설정
Vector<Integer> v = new Vector<Integer>(Arrays.asList(num, num, num)); // 생성시 값 추가
v.add(value);
v.add(null);
v.add(index, value);
// Class객체 List추가방법
Class Class{
string name;
int age;
}
Class c = new Class(name, age);
vc.add(c);
vc.add(new Class(name, age));
v.remove(value);
v.removeAllElements();
v.clear();
v.size(); // 현재 존재하는 value량
v.capacity(); // 전체 value량
// 요소구하기
for(Integer i : list)
Iterator<Integer> iter = v.iterator();
while(iter.hasNext()) {
iter.next();
}
v.get(value); // value of index return
v.contains(value); // value가 존재하는지 검색, nonexistent = null
v.indexOf(value); // value가 존재하는 index return
◎ 2D ArrayList, Vector
그래프, 경로를 저장하고자 할 때!
ArrayList<Integer> aL[] = new ArrayList[1001]; //2차원 리스트 선언
for (int i = 1; i <= N; i++)
aL[i] = new ArrayList<Integer>(N + 1); //각 리스트 용량 선언(초기화)
for (int i = 0; i < M; i++) {
aL[fs].add(se); // 경로삽입
aL[se].add(fs); // 경로삽입
}
Vector<Integer> v[] = new Vector[1001]; //2차원 벡터 선언
for (int i = 1; i <= N; i++)
v[i] = new Vector<Integer>(N + 1); //각 벡터 용량 선언(초기화)
for (int i = 0; i < M; i++) {
v[fs].add(se); // 경로삽입
v[se].add(fs); // 경로삽입
}
◎ Collections Sort
//LinkedList, ArrayList, Vector
Collections.sort();
● Queue Collections
◎ Queue
Queue <type> q = new LinkedList<>();
q.add(value); // 값 추가
q.offer(value); // 값 추가
q.poll() // queue 첫값 반환(반환하며 제거), isEmpty -> return null
q.remove() // queue 첫값 제거
q.clear() // queue 초기화
q.peek() // queue 에 맨 처음 저장된 값 참조
◎ PriorityQueue
PriorityQueue<type> q = new PriorityQueue<>(); // 낮은 숫자 우선순위
PriorityQueue<type> q = new PriorityQueue<>(Collections.reverseOrder()); // 높은 숫자 우선순위
q.add(value); // 값 추가
q.offer(value); // 값 추가
q.poll() // queue 첫값 반환(반환하며 제거), isEmpty -> return null
q.remove() // queue 첫값 제거
q.clear() // queue 초기화
q.peek() // queue 에 맨 처음 저장된 값 참조
◎ PriorityQueue + Custom Class
우선순위큐에 클래스타입을 생성하는 방법!
★ Class에서 Comparable을 상속받아 compareTo를 구현해야함!!
class xy implements Comparable<xy>{
int y, x; // y:row, x:column
xy(int y, int x) {
this.y = y;
this.x = x;
}
/*Getter, Setter구현*/
@Override
public int compareTo(xy o) {
if (this.y > o.getY())
return 1;
else if (this.y < o.getY()) {
return -1;
else {
if (this.x >= o.getX())
return 1;
else if (this.x < o.getX())
return -1;
}
return 0;
}
}
PriorityQueue<xy>pq = new PriorityQueue<xy>();
PriorityQueue<xy>pq = new PriorityQueue<xy>(Collections.reverseOrder());
● Map Collections
◎ Hashtable
◎ HashMap
Key, Value로 구성된 테이블. 특정 Value에 대응되는 Value를 찾거나,
HashMap<type, type> m = new HashMap<type, type>(); // 기본선언
HashMap<type, type> m = new HashMap<>(); // parameter생략
HashMap<type, type> m = new HashMap<type, type>(m); // 기존 map복사
HashMap<type, type> m = new HashMap<type, type>(value); // 초기 용량(capacity)설정
HashMap<type, type> m = new HashMap<type, type>(value, float); // capacity, load factor지정
HashMap<type, type> m = new HashMap<type, type>() {{ // 초기값 설정
put(value, value);
put(value, value);
...
}};
m.put(value, value); // 값 생성
m.remove(value); // value of key 삭제
m.clear(); // 초기화
m.size();
m.isEmpty();
m.containsKey(value);
m.containsValue(value);
m.setValue(value) // 해당 값 변경
//예시
for(Map.Entry item : m.entrySet()) {
if (m.getValue().equals(value))
m.setValue(new_value);
}
// 출력방법 3가지 (get, EntrySet, KeySet)
m.get(value);
//EntrySet()
for(Entry<type, type> entry : m.entrySet()) {
entry.getkey(), entry.getValue(); // key, value
}
for(Map.Entry item : m.entrySet()) {
m.getKey(), m.getValue();
}
//KeySet()
for(type item : m.keySet()) {
item, m.get(item) // key, value
}
//Iterator()
Iterator<Entry<type, type> > entries = m.entySet().iterator();
while(entries.hasNext()) {
Map.Entry<type, type> entry = entries.next();
entry.getKey(), entry.getValue();
}
Iterator<type> keys = m.keySet().iterator();
while(keys.hasNext()) {
int key = keys.next();
key, m.get(key);
}
first_map.putAll(second_map) // HashMap 병합
◎ TreeMap
TreeSet과 동일하게 Red-Black Tree를 사용.
단 Set은 값만 저장한다면, TreeMap은 키, 값의 Map, Entry를 저장함
데이터저장시에 추가, 삭제가 HashMap보다 느리지만, 정렬된상태로 Map을 유지하거나 조회하는경우 효율성이 높음
TreeMap<type, type> m = new TreeMap<type, type>();
TreeMap<type, type> m = new TreeMap<>();
TreeMap<type, type> m = new TreeMap<type, type>(m);
TreeMap<type, type> m = new TreeMap<type, type>() {{
put(value, value);
put(value, value);
}};
m.put(value, value);
m.remove(value)
m.clear();
m.size();
m.isEmpty();
m.containsKey(value);
m.containsValue(value);
m.get(value);
m.firstEntry();
m.firstKey();
m.lastEntry();
m.lastKey();
// 출력방법 3가지 (get, EntrySet, KeySet)
m.get(value);
//EntrySet()
for(Entry<type, type> entry : m.entrySet()) {
entry.getkey(), entry.getValue(); // key, value
}
for(Map.Entry item : m.entrySet()) {
m.getKey(), m.getValue();
}
//KeySet()
for(type item : m.keySet()) {
item, m.get(item) // key, value
}
//Iterator()
Iterator<Entry<type, type> > entries = m.entySet().iterator();
while(entries.hasNext()) {
Map.Entry<type, type> entry = entries.next();
entry.getKey(), entry.getValue();
}
Iterator<type> keys = m.keySet().iterator();
while(keys.hasNext()) {
int key = keys.next();
key, m.get(key);
}
[ Wrapper Class / 와퍼, 래퍼 ]
기본타입을 객체로 다루기위해사용하는 클래스
*기본타입 : primitive type : char, int, float, double, boolean
*참조타입 : reference type : class, interface
Compiler가 자동 박싱(AutoBoxing)과 자동 언박싱(AutoUnBoxing)을 처리해주기에 다음과같은 연산이가능함
Integer first = new Integer(value);
Integer second = new Integer(value);
int num = value;
first == i; // 가능
first.equals(i); // 가능
first == second; // 불가능
// 이유 :: == 연산자는 참조주소를 비교하고, 두 래퍼객체는 서로의 참조주소가 다르기때문에 값이같아도 다르다고 판단됨
first.equals(second); // 가능
[ Generic / 제네릭 ]
객체생성시에 동적으로 Type을 결정할 수 있는 방식.
(Type) : Generic<T>, Generic<A,B,C>
(Element) : ArrayList<E>