java.lang : 일반적으로 많이 사용하는 클래스들이 여기에 포함.
java.util : 유틸리트 클래스들이 포함
java.lang 패키지에는 Object라는 클래스가 있는데, Object 클래스는 자바의 최상위 클래스로 우리가 만드는 모든 클래스의 부모 클래스가 된다. 그래서 클래스를 선언할 때 extends Object 라고 명시하지 않아도 모든 클래스가 된다. 그래서 클래스를 선언할 때 extends Object라고 명시하지 않아도 모든 클래스는 항상 Object 클래스를 부모 클래스로 가지고 있다. java.lang 패키지에 있는 문자열 관련 클래스들인 String, StringBuffer, StringBuilder 클래스도 하나씩 학습합니다. 또한 기본 자료형에 대응하는 wrapper 클래스와 수학 관련 함수들을 모아 놓은 Math 클래스, java.util패키지에 있는 Random 클래스를 알아가보자
자바는 클래스와 인터페이스 간에 상속 관계로 연결되어 있고, 자바의 최상위 클래스는 Object 클래스로 모든 클래스의 부모가 됩니다. 모두 Object 클래스를 자동적으로 상속 받고 있는거와 다름없다.
package equals;
class Thing extends Object{
private String name;
private int count;
Thing(){}
Thing(String name, int count){
this.name = name;
this.count = count;
}
void print(){
System.out.println("name : " + name);
System.out.println("count: " + count);
}
public boolean equals(Object obj){
if(this.name.equals(((Thing)obj).name) && this.count ==((Thing)obj).count){
return true;
}else{
return false;
}
}
}
public class Main {
public static void main(String[] args){
Thing th1 = new Thing("desk", 5);
Thing th2 = new Thing("desk",5);
if(th1.equals(th2)){
System.out.println("Same thing");
}else{
System.out.println("Diff");
}
}
}
// 그냥 == 연산자만 사용했을때는 객체의 참조값만 비교하기때문에 당연이 값이 같이 나오더라도 펄스가 형성이되는데
//equals메소드를 오버라이딩해서 두 인스턴스가 독립되어 있다고해도 변수의 값이 같다면 true로 변환하도록 한다
package tostring;
class Thing{
private String name;
private int price;
Thing(String name, int price){
this.name = name;
this.price = price;
}
void show(){
System.out.println("name : " + name + ",price :" + price );
}
}
public class Main {
public static void main(String[] args){
Thing t = new Thing("book", 20000);
String s= t.toString();
System.out.println(s);
System.out.println(t);
t.show();
}
}
package tostring;
class Thing{
private String name;
private int price;
Thing(String name, int price){
this.name = name;
this.price = price;
}
public String toString(){
return "name: "+name+",price : " + price;
}
}
public class Main {
public static void main(String[] args){
Thing t = new Thing("book", 20000);
String s= t.toString();
System.out.println(s);
System.out.println(t);
t.show();
}
}
원래의 toString()은 인스턴스틔 참조값을 반환하는 메소드인데 2번째 코드에서 show()메소드오 ㅏ같이 나오게 하려면
toString()을 오버라이딩해서 바꾼다면 인스턴스를 문자열로 바꿀수 있다.
자바에서 문자열을 다루는 클래스로 String, StringBuffer, StringBuilder 가 있고, 주로 String 클래스를 이용하고있지만, String 클래스를 자세히 학습하고 StringBuffer 와 StringBuilder를 알아보자
String 클래스는 주로 System.out.println()메소드의 괄호 안에서 주로 사용햇는데, 이제는 구체적으로 생성자와 다양한 String 메소드를 사용해보자
다른 인스턴스 생성과 마찬가지로 new 키워드 이용
간단하게 쌍따옴표만으로 생성
다음은 "Hello"라는 String 인스턴스를 생성하는 코드이며, 두 코드는 문자열을 생성한다는 것은 같지만 약간의 차이가 있다.
String s1 = new String("Hello w 0orld");
String s2 = new String("Hello world");
if(s1 == s2) System.out.println("s1 == s2");
else System.out.println("s1 != s2 ");
String s3 = "Java Programming";
String s4 = "Java Programming";
if(s3 == s4) System.out.println("s3 == s4");
else System.out.println("s3 != s4");
s1 != s2
s3 == s4
1과 2 에서는 new 키워드를 이요하여 문자열 인스턴스가 생성이 되어있는데, 이런경우에는 무족너 새로운 인스턴스가 생성이 되기떄문에 문자열뿐만 아니라 new 를 이용하여 인스턴스를 생성하면 어떤 클래스든지 항상 새로운 인스턴스가 생성된다.
3에서 s1과 s2가 같은지를 비교하는데, 이때는 두 인스턴스가 같은 참조값을 갖는지를 비교하는 것, 따라서 서로 다른 인스턴스이므로 else가 수행된다
5 와 6 에서도 똑같은 문자열을 생성하는데, 이번에는 new 키원드 없이 따옴표로 간단하게 인스턴스를 생성했고, 이런 경우에는 new로 생성할 떄와는 다르게 이미 생성한 똑같은 문자열이 있다면 새로 생성하지 않고 이미 생성된 똑같은 문자열이 있다면 새로 생성하지 않고 이미 생성된 인스턴스에 이름을 하나 더 붙인다.
s3 = "Java Programming"
s3-> java Programming
s4 = "Java Programming"
s4 는 s3를 바라보고 있으며 이름만 하나더 생긴다
또한
만약
String x = new String("Good morning");
String y = "Good morning";
if(x == y){
System.out.println("x==y");
}else{
System.out.println("x !=y");
}
결과는 x!=y
이유는 인스턴스 주소가 다르기 때문
그리고 문자열로만 인스턴스를 만들었을경우에는 따로 인스턴스를 더 생성하지 않고 이름만 하나더 붙임
참고로 다음과 같이 new를 이용한 인스턴스와 따옴표를 이요한 인스턴스도 같은 문자열이라고 하더라도 공유하지 않음을 알아두자
String x = new String("Good morning");
String y = "Good moring";
if( x == y) System.out.println("x == y");
else System.out.println("x !=y";)
결과는 x != y
| 메소드 | 설명 |
|---|---|
| char charAt(int index) | 명시된 인덱스에 해당하는 문자를 반환함 |
| int compareTo(String anotherString) | 두 문자열을 사전식으로 비교 |
| String concat(String str | 문자열 뒤에 str을 연결함 |
| boolean contains(CharSequence s) | 문자열에 s가 포함되어 있다면 true 반환.else false |
| boolean equals(Object anObject) | 문자열과 anObject가 같은 문자열인지 판단하여 true or false 반환 |
| int indexOf(int ch) | 문자 ch가 있다면 그 위치 인덱스를 반환함. ch가 여러개 있다면 가장 앞에 있는 인덱스를 반환 |
| int length() | 문자열의 길이를 반환함 |
| String replace(char oldCh,char newCh | 문자 oldCh를 newCh로 변환하고 새로 변환된 문자열을 반환함 |
| String toString() | Object 클래스의 toString() 메소들르 오버라이딩한 것으로 문자열 자체를 반환함 |
String x = new String("Hello world");
String y = new String("x == y")
if(x.equals(Y)) System.out.println("x equals y");
else System.outl.println("x not equals y")
결과 x ! = y
x equals y
== 은 위에서 설명햇듯이 양쪽의 인스턴스가 동일한 인스턴스인지를 판단하기 때문에 new를 이용하여 각각 만들어진 인스턴스는 동일하지 않기 떄문에 x !y 가 출력되고, equals 메소드는 두 인스턴스 값이 실제로 같은지 판단, 따라서 두 인스턴스의 값이 같은지를 알고 싶을때는 equals 메소드를 사용해야 한다. 그러니까 String 클래스는 equals 메소드가 오버라이딩 되서 사용자 가 편하게 사용할수 있도록 제공
java.lang.StringBuffer
문자열 클래스 중에서 StringBuffer 클래스를 살펴보자 StringBuffer 인스턴스는 반드시 new키워드를 사용해서 생성해야한다.
StringBuffer 생성자를 살펴 보자
StringBuffer() -> 크기 16인 빈 문자열이 생성됨.
StringBuffer(int capacity) -> capacity 값을 주면 그 크기로 빈 문자열이 생성됨
StringBuffer(String str) -> 문자열 str로 초기화하는 인스턴스가 생성됨.
package code185;
public class Code185 {
public static void main(String[] args)
{
StringBuffer sb1 = new StringBuffer("Good morning");
sb1.append('!');
sb1.append(" Alice!");
System.out.println(sb1);
StringBuffer sb2 = new StringBuffer("water");
StringBuffer sb3 = new StringBuffer("wafer");
System.out.println("sb2.charAt(2) : " + sb2.charAt(2));
System.out.println("sb2.compareTo(sb3) : " + sb2.compareTo(sb3));
StringBuffer sb4 = new StringBuffer("Java Programming Language");
sb4.delete(5, 8);
System.out.println("sb4.delete(5,8) : " + sb4);
StringBuffer sb5 = new StringBuffer("Hello world");
sb5.insert(5, ',');
System.out.println("sb5 : " + sb5);
System.out.println("sb5.substring(7) : " + sb5.substring(7));
System.out.println("sb5 : " + sb5);
System.out.println("sb5.capacity( ) : " + sb5.capacity( ));
sb5.trimToSize( );
System.out.println("after trim : " + sb5.capacity( ));
}
}
package stringbuffer;
class tostringandbuffer{
public static void main(String[] args){
StringBuffer sb1 = new StringBuffer("Hello world ");
StringBuffer sb2 = new StringBuffer("Hello world ");
String a = sb1.toString();
String b = sb2.toString();
System.out.println(sb1);
// if(sb1.equals(sb2)) System.out.println("sb1 equals sb2");
// else System.out.println("sb1 does not equal sb2");
if(a.equals(b))System.out.println("equal");
else System.out.println("not equal");
}
}//"sb1 does not equal sb2"
String 클래스와 StringBuffer 클래스의 차이는 , String 클래스가 StringBuffer 클래스보다 사용이 좀 더 편해 보일수 있지만 StringBuffer또한 장정이 있다. String 인스턴스는 immutable(변경불가능)하지만 StringBuffer 인스턴스는 mutable(변경가능)하다. 따라서 String 인스턴스는 한번 생성하면 변경할 수가 없고 변경된 새로운 인스턴스가 계속 만들어진다. 이에 반해 StringBuffer 인스턴슨느 변경이 가능하기 때문에 같은 인스턴스가 계속 변경될수 있다. 두 클래스의 메소드들을 비교해보면 StringBuffer 클래스는 인스턴스를 수정할수 메소드 append.delete.insert 등과 같은 메소드들이 많은 반면에 String 클래스는 그러한 메소드들이 별로 없다.
만약에 "computer" 라고 실수로 't'를 빠뜨렸다면 String 인스턴스는 다음과 같이 새롭게 String 인스턴스를 구성해야 한다. 이에 반해 StringBuffer 인스턴스는 insert 메소드를 이용해서 기존의 인스턴스를 직접 수정할 수가 있다.
package stringbuffer;
public class Sb {
public static void main(String[] args){
String s = new String("compuer");
String new_s = s.substring(0,5) +'t'+ s.substring(5);<복잡함
System.out.println("new_s: " + new_s);//불변성이기때문에 새로운 인스턴스를 생성해서 하고있음
StringBuffer sb = new StringBuffer("compuer");
sb.insert(5,'t'); <간편함
System.out.println("sb:" + sb);
}
}
StringBuilder 클래스는 mutable한 문자열 클래스라는 점에서 StringBuffer 클래스와 많이 유사하다. 생성자도 같으며, 같은 메소드들이 많이 존재한다. 둘의 가장 큰 차이는 StringBuffer 인스턴스는 스레드에서 이용 가능하고 StringBuilder는 스레드에서 이용할수 없다.
StringBuilder 클래스의 생성자는 StringBuffer 클래스와 유사하며, 또한 메소드들도 StringBuffer 클래스와 거의 같다. 따라서 앞의 예제에서 StringBuffer를 모두 StringBuilder 클래스로 바꾸어서 수행해도 똑같은 결과가 나옵니다. 똑같은 코드가 중복되니 잘 확인해보자
https://ifuwanna.tistory.com/221 참조
StringBuffer는 동기화 키워드를 지원하여 멀티쓰레드 환경에서 안전하다는 점이며(String또한 불변성이라 안전성을 가지고있다)
StringBuilder 는 동기화를 지원하지 않기 떄문에 멀티스레드는 비적합하지만 동기화를 고려하지 않아 단일쓰레드에서는 Buffer보다 띄어나므로 상황에따라 쓰자
String : 은 문자열 연산이 적고 멀티쓰레드 환경일경우
StringBuffer : 문자열 연산이 많고 멀티쓰레드 환경일 경우
StringBuilder : 문자열 연산이 많고 단일쓰레이거나 동기화 고려를 하지 않을때
//급메모 정적메소드는 클래스를 이용해 호출
수학관련 클래스이며 사용빈도가 높다 . Math 클래스는 생성자가 없고 두 개의 상수와 메소드들로 이루어져 있고, 그리고 모든 메소드들은 정적 메소드로 인스턴스 생성없이 사용할수 있다
package mathclass;
public class Main {
public static void main(String[] args){
System.out.println("1. " + Math.abs(-3.5));
System.out.println("2. " + Math.ceil(-3.5)); // js 랑은 반대이군.. 반내림 js는 반올림
System.out.println("3. " + Math.floor(-3.5));// java에서는 (a)이하의 가장큰수 를 반환함 그렇다면 4
System.out.println("4. " + Math.max(2.7,6.8));//둘중의 가장큰것
System.out.println("5, " + Math.min(-3.5, -5.5));
System.out.println("6, " + Math.pow(2,10));
System.out.println("7, " + Math.round(3.7));
System.out.println("8, " + Math.sqrt(25));
}
}
1. 3.5
2. -3.0
3. -4.0
4. 6.8
5, -5.5
6, 1024.0
7, 4
8, 5.0
코딩을 하다보면 자바의 기본 자료형(boolean, char, byte, short, int, long , float, double)을 인스턴스로 변환하여 사용해야 하는 경우가 있다. wrapper 클래스가 이때 필요하며, wrapper 라는 이름의 클래스가 있는것은 아니고, 기본 자료형 각각에 대응하는 클래스들을 통틀어서 wrapper클래스라고 부른다
각 첫글자만 대분자로 시작한다
Number 클래스는 6개의 숫자 관련 클래스의 상위 클래스이며, Boolean 과 Character 클래스는 Number 클래스와 관계가 없고, 상속 관계에 있으니 6개 관련 클래스들은 모두 Number 클래스에 있는 메소드들을 사용할수 있다. Number 클래스 구성을 살펴보자
| 메소드 | 설명 |
|---|---|
| byte byteValue() | byte 값으로 변환 |
| abstact double doubleValue() | double 값으로 변환 |
| abstract float floatValue() | float 값으로 변환 |
| abstract int intValue() | int값으로 변환 |
| abstract shortValue() | short 값으로 변환 |
| abstact long longValue() | long 값으로 변환 |
Byte,Short, Integer,Long 클래스는 모두 정수형 데이터를 인스턴수화 할수 있도록 하며, 4개의 클래스 구성이 유사하므로 Integerer 클래스의 필드 중에 유용한 것은 Max_Value,Mina_Value 이다
static int Max_VALUE = 가장 큰 정수 값을 가지고 있음
static int Min_Value = 가장 작은 정수 값을 가지고 있음
1 int intValue() : Integer 인스턴스를 int로 변환하여 변환함
2 static int paseInt(String s) : 문자열 정수 변환
3 static Integer valueOf(int i) : int 값을 Integer 인스턴스로 변환하여 변환
4 static Integer valueOf(String s) : 문자열 s를 Integer 인스턴스로 변환하여 변환
기본형 객체를 -> Wrapper형식으로 가 박싱
언박싱은 반대
Integer x = new Integer(100) //박싱
int y = x.intValue(); // unBoxing
오토박싱
Integer x = 100; // autoBoxing(100이 자동으로 인스턴스 x변환);
오토 언박싱
Integer x = new Integer(100);
int y = x;//자동으로 기본 자료형 변환