Day 1
1. 8가지 자료형
Byte | Short | Int | Long | Float | Double |
8bit | 16bit | 32bit | 64bit | 32bit | 64bit |
- byte , short , int, long은 정수의 값을 가져다 저장할 수 있는 자료형
- 작은 타입 => 큰 타입 (자동 변환)
- 큰 타입 => 작은 타입 (강제 변환 -> X : 에러)
- (기본) 같은 타입형 변수만 연산 가능
2. 변수 : 값을 저장하는 기억공간
- 자료형 : 변수 선언
- 대입 : 값을 저장
문제
1. 연 6.6퍼 이자율에 초기금 100만원을 100년간 묵힐 때
public class Test1{
pulblic static void main(String[] args){
double money = 1000000; //초기금
double rate = 0.066; //이자율
for( int i = 0; i < 100; i++){
money += money * rate;
}
System.out.println((int)money);
}
}
2. 연 6.6% 이자율의 복리 (매 100만원 적금)
public class Test2{
public static void main(String[] args){
int addMoney = 1000000; //매 적금
double money = 0; // 초기금
double rate = 0.066;
for(int i = 0; i < 100; i++){
money += addMoney;
money += money * rate;
}
System.out.println(money);
long endTime = System.currentTimeMiilis();
}
}
Day 2
※코드 잘 짜는 법
- 잘 쪼갠다
- 자신의 보폭을 잘 파악한다
- 반복문 정리 => 일단 늘어놓고 정리
1. Java
-선언 , 대입, 연산
- 클래스에서 변수, 함수 선언 가능
- 클래스에서 변수, 함수 호출 연산, 초기화 등등 불가능
class Apple{
int i ;
i = 100; //error
int add(int i, int j){
return 100;
}
add(); //error
}
- 참조형 변수
- Apple t = new Apple(); => 클래스를 선언하고 new를 이용하여 instance를 가리킴
class Apple{
int i;
int add(int i, int j){ return 100;};
}
public class Test023 {
public static void main(String[] args) {
Apple t = new Apple(); //에러 x -> 참조형 변수(포인터)
t.i = 100; // t가 가리키는 인스턴스가 가지고 있는 변수 i
System.out.println(t.add(100,20)); //t가 가리키는 인스턴스가 가지고 있는 함수
}
}
2. 요약
- 클래스를 선언하여 인스턴스를 만듬 => 이 떄, new 사용
- 클래스 내부 (멤버 함수(멤버 변수))
- 클래스 - 인스턴스 - new : 멤버 변수, 멤버 함수존재
- 인스턴스가 만들어지는 시점에 멤버변수 메모리 할당
- 함수 호출 시점에 로컬변수가 메모리 할당
- 참조형 변수 는 인스턴스를 가리키는 용도 / 클래스 이름으로 선언
- 자료형 변수 는 자바의 기본 8개 자료형
- 자료형 변수에서 대입 ( i = t ) -> t의 값을 복사해서 i에 대입
- 참조형 변수에서 대입 ( i = t ) -> t가 가리키는 대상을 i가 가리킴
- 생성자 함수 는 클래스의 멤버 함수 => 주로 멤버변수를 초기화 하는데 사용 (constructor)
- 인스턴스가 생성될 때 생성자 함수가 생성됨
문제
1. 단리, 복리 가능한 C프로그래밍 (매 100만원 적금)
#include <stdio.h>
float danri(float money, int year, float rate){
int i;
float totalMoney, mainMoney;
totalMoney = 0;
mainMoney = 0;
for (i=0; i<year; i++){
mainMoney += money;
totalMoney += mainMoney * rate + money;
}
return totalMoney;
}
float bokri(float money, int year, float rate){
float moneyStart;
int i;
moneyStart = 0;
for (i=0; i<year; i++){
moneyStart += money;
moneyStart += moneyStart * rate;
}
return moneyStart;
}
int main(){
float (*fp)( float, int, float);
float r;
fp = danri;
r = fp( 100.0, 100, 0.066);
printf("%f\n", r);
fp = bokri;
r = fp( 100.0, 100, 0.066);
printf("%f\n", r);
return 0;
}
Day 3
1. 객체지향 3대 속성
- 상속성 : 클래스를 상속해서 클래스를 만든다
- 은닉성 : 감추고 싶은 건 감출 수 있다
- 다형성 : 하나의 심볼(이름)이 여러 실체에 매핑될 수 있다.
class A {
int apple = 10;
}
//클래스 B는 클래스 A를 상속하여 만들었음을 명시.
// A에서 선언한 멤버변수는 멤버함수를 내려받겠다.
class B extends A{
int add(int i, int j){return 100;}
}
public class Test27 {
public static void main(String[] args) {
B t = new B();
System.out.println(t.apple);
}
}
2. 클래스 : 설계도 정의해 놓은 것
- 할 수 있는 것 : 참조형 변수 선언 / 인스턴스 생성 / 상속받아 클래스 선언
3. 생성자
<특징>
- return 타입 X
- 클래스명 (매개 변수) {.....} 로 동작
- 인스턴스 생성시점 호출
- 함수 아님 .. 인스턴스 멤버 변수를 초기화 시킬 때 주로 사용
class Apple4{
int data = 0;
// return이 존재하지 않는 함수를 서브루틴이라 한다.
//리턴타입을 void로 한다.
void print(){
System.out.println(this.data);
}
}
public class Test28 {
public static void main(String[] args) {
Apple t = new Apple();
t.data = 10;
t.print();
Apple l = new Apple();
l.data = 20;
l.print();
}
}
//출력 : 10 20
this : 멤버 함수 안에서 자신이 소속된 인스턴스에 대한 포인터
4.Java로 리스트 만들기
연결리스트
class Node{ //외워라!
int data = 0; // 대입은 원래 불가능하나 선언과 동시에 대입은 가능함
Node next = null; //가리키고 싶지않다.
Node( int i , Node n){ //생성자 일반적 예시
this.data = i;
this.next = n;
}
}
public class Test5 {
public static void main(String[] args) {
Node head = new Node(0,null); //Step 1
Node tail = head;
tail.next = new Node(10, null); //Step 2
tail = tail.next;
tail.next = new Node(20, null); //Step 3
tail = tail.next;
for( Node t =head.next ; t !=null ; t=t.next){ //Step 4
System.out.println(t.data);
}
}
}
/*
모든 참조형 변수에는 null 이라는 값이 대입 가능 : 가리키는 인스턴스 없다.
-어떻게 돌아가는지 상황파악을 그림으로 설명 가능할 것.
>> 출력 : 10 20
*/
- 객체 상태 변화
연결리스트 클래스화
class Node{
int data = 0;
Node next = null;
Node( int i , Node n){
this.data = i;
this.next = n;
}
}
class LinkedList {
Node head = null;
Node tail = null;
public LinkedList() {
this.head = new Node(0, null);
this.tail = this.head;
}
void add(int i){
tail.next = new Node(i, null);
tail = tail.next;
}
public void print() {
for (Node t = head.next; t !=null; t=t.next) {
System.out.println(t.data);
}
}
}
public class Test29 {
public static void main(String[] args) {
LinkedList l = new LinkedList(); //Step 1
l.add(10); //Step 2
l.add(20); //Step 3
l.print();
}
}//>> 출력 : 10 20
- 객체 상태 변화
5. Java 상속
class A{
A(){
System.out.println("A constructor");
}
}
class BB extends A{
B() {
System.out.println("B constructor");
}
}
public class Test31 {
public static void main(String[] args) {
new B();
}
}//>> A constructor B constructor
=> 왜? A constructor B constructor 이렇게 출력이 될까?
>> 생성자는 상속이 되지 않고 호출 되는 것이기 때문(멤버 함수가 아니라서)
-상속관계가 존재 시 조상 클래스 , 자손 클래스 자손의 인스턴스를 생성하면 조상의 생서자가 먼저 호출, 자손의 생성자가 호출된다
>>> 이 때 인스턴스는 2번 생성되는 것 처럼 보이지만 하나가 생성되고 조상과 자손을 호출한다.
class A{
void print(){
System.out.println("A print");
}
}
class B extends A{
void print(){
System.out.println("B print"); // method overriding
super.print();// 부모의 함수를 호출하고 싶을때
void print2(){
System.out.println("B print2");
}
}
public class Test32 {
public static void main(String[] args) {
B t = new B(); //자손 B호출
t.print();
A t2 = new A(); //조상 A 호출
t2.print();
A t3 = new B(); //자손 B 호출
t3.print();
//조상에서 선언된 멤버함수, 멤버변수만 호출 가능
//t3.print()2; -------> 에러남
//B t4 = (B) new A();//에러남 캐스팅되지않음
//t4.print(); //다운캐스팅은 일반적으로 불가
B t4 = (B) t3; //이 경우 다운캐스팅이됨
t4.print(); //JVM이 무슨형인지 추리할수 있기때문
}
}//결과값 : B print A print A print B print A print
6. Method overriding : 조상클래스에서 선언한 멤버 함수 재정의
- 각 인스턴스에서 정의된 method로 사용(변수는 오버라이딩 X)
- Super 을 이용하여 자손 클래스에서 조상 method 이용가능
7. 접근 제어자
상속 | 외부 호출 | 내가 쓰기 | |
Private | X | X | O |
protected | O | X | O |
public | O | O | O |
- 클래스 안의 멤버함수와 멤버 변수 앞에 붙임
- java 의 protected => 같은 패키지 내에선 접근 가능 / 다른 패키지 내에선 접근 불가
- 접근자 안적어? => friendly로 (같은 패키지로는 public / 다른 패키지는 private)
=> 때문에 Getter을 이용하여 자신의 값을 호출하게 만듬
class A{
private int data =100;
public int getData(){ return data;}
}
class B extends A{
private int data =200;
public int getData(){return data;}
}
public class Test{
public void static main(String[] args){
A t = new B();
System.out.println(t.getData());
}
}//결과값 : 200
-B 클래스의 getData가 호출이되서 혼란이 방지됨
-조상에서 getXXX 함수가 보이면 그런 변수가 있는줄 알고 xXX 변수는 피해간다
-이 경우 getData()로 부모클래스의 data를 부르려고 하면 getData()가 오버라이딩 되어있기 때문에 접근이 힘들어진다.
8. 추상클래스 : 선언되었지만 구현되어 있지 않은 메소드
abstract class A{
public abstract void print();
}
abstract class B{}
class C extends B{}
abstract class D extends C{}
public class Test1 {
public static void main(String[] args) {
// A t = new A();
A t = null;
}
}
-abstract 메소드가 하나라도 선언되어 있으면 그 메소드 가진 클래스는 반드시 abstract 클래스로 정의
-abstract 클래스는 인스턴스를 만들 수 없다
-참조형 변수 선언이 가능하다
-상속 또한 가능하다
abstract class A{
public abstract void print();
}
abstract class B extends A{} // <------- abstract class - abstract class
class C extends A{ // <------abstract 클래스가 아닌 클래스가 상속받으려면 구현해줘야 함
@Override
public void print() {
System.out.println("hi");
}
}
public class Test1 {
public static void main(String[] args) {
A t = new C(); // <------ 조상의 함수를 호출한 경우 , 자손의 함수가 호출, 오버라이딩 된 구현부가 호출
t.print();
}
}
<단리, 복리 추상 클래스로 구현>
abstract class Bank{
public abstract double calc(double money, int years, double rate);
public void print(){
double r = calc(100, 100, 0.066);
System.out.println(r);
}
}
class BokriBank extends Bank{
@Override
public double calc(double money, int years, double rate) {
return 59665.1234 * subCalc();
}
private int subCalc(){return 3;}
}
class DanriBank extends Bank{
@Override
public double calc(double money, int years, double rate) {
return 760.0 + money();
}
private int money(){return 100;}
}
public class Test2 {
public static void main(String[] args) {
Bank bk = new BokriBank();
bk.print();
Bank bk2 = new DanriBank();
bk2.print();
}
}
9. 인터페이스
interface ICalc{
public void print(); //인터페이스 안에는 모두 추상자료형이여야함
}
interface IUnknown{}
class Apple{}
class Calc extends Apple implements ICalc, IUnknown{
@Override
public void print() {
System.out.println("A");
}
}
public class Test3 {
public static void main(String[] args) {
ICalc ic = new Calc();
ic.print();
}
}
-일종의 추상 클래스 => 변수 선언, 상속 당할 수 있음 => 다만, 인스턴스 생성 불가
-인터페이스 상속해서 클래스를 선언될 때는 implements 이용
-다중 상속 가능, 클래스 상속과 인터페이스 동시 상속 가능
문제
<인터페이스 사용한 Decorator pattern>
interface IGreet {
public String greet();
}
class MerciGreet implements IGreet{
@Override
public String greet() {
return "Merci";
}
}
class HelloGreet implements IGreet{
@Override
public String greet() {
return "hello";
}
}
abstract class GreetDeco implements IGreet{
protected IGreet ig = null;
public GreetDeoo(IGreet ig) {
this.ig = ig;
}
}
// 자손의 생성자에서 조상의 생성자 중 매개변수 있는 생성자를 호출 원하면 supoer로 지정.
class StarDeco extends GreetDeoo{
public StarDeco(IGreet ig) {
super(ig);
}
@Override
public String greet() {
return "" + ig.greet() + "*";
}
}
class SharpDeco extends GreetDeoo{
public SharpDeco(IGreet ig) {
super(ig);
}
@Override
public String greet() {
return "" + ig.greet() + "#";
}
}
public class Test4 {
public static void main(String[] args) {
IGreet ig= new SharpDeco(new StarDeco(new HelloGreet()));
System.out.println(ig.greet());
}
}//hello*#
=> 추가 상식 : interface는 public 명시 안해도 컴파일시 자동으로 추가해줌
Day 4
1. 메소드 오버로딩 : 하나의 클래스 안에 이름은 같은데 매개변수 형태가 다른 함수 여러 개 공존 가능
class Temp{//하나의 클래스 안에 이름은 같은데 매개변수 형태가 다른 함수 여러 개 공존가능
public void print(){};
public void print(int i){
System.out.println(1);
};
public void print(double i){
System.out.println(2);
};
public void print(int i, int j){
System.out.println(3);
};
}
public class Test40 {
public static void main(String[] args) {
Temp t= new Temp();
t.print();
// float j = 3.14; 큰타입 Double(3.14) -> 작은타입 float(j)로 바로 변환 x
float i = (float) 3.14; //방법 1 강제형변환
float j = 3.14f; //방법2 float = float
t.print(j);// 매개변수가 딱 맞지 않으면 가장 가깝게 자동형변환 되는것을 찾아서 호출
}//>>결과 : 2
}
- 멤버 함수에는 오버라이딩 이라는 개념이 있지만, 멤버 변수에는 오버라이딩 개념이 없음
class A{
int i = 100;
}
class B extends A{
int i = 200;
void print(){};
}
public class Test40 {
public static void main(String[] args) {
A t1 = new B();
System.out.println(t.i);
//t 포인터가 가리키는 인스턴스를 감싸는 B클래스 인스턴스를 t2가 가리킨다.
B t2 = (B)t;
t2.print();
System.out.println(t2.i); //갑자기 i값이 변하므로 private해주는게 좋음
}
}
##요약
- 형변환 시 예기치 못한 변수의 변화가 생길 수 있으므로 같은 이름으로 하는 것은 금지
- 클래스 안에 올 수 있는 것
-변수 선언(멤버 변수) , 함수 선언(멤버 함수)- 실행 하면 main이 먼저 올라오고
- static으로 선언되면 클래스가 메모리에 올라올 때 인스턴스가 생성되기 전에 메모리 할당
- 자바 실행 환경은 클래스가 필요해지면 클래스 파일을 메모리에 올린다 -> 후에 인스턴스 생성 가능
- static 멤버는 클래스 로딩 시에 메모리를 할당, 무조건 유일하다
- non-static 멤버는 인스턴스가 생성 될 때 메모리를 할당받음 , 인스턴스마다 따로따로 존재
- 인스턴스가 100번 생성되도 클래스는 설계도이니 최초에 한번만 올라옴 / 이 때 스태틱은 전역변수처럼 1개만 올라옴
class Temp{
static int i = 100;
static void print(){
System.out.println(i);
}
void func(){
System.out.println("hi");
}
static class Temp2{
private int i = 3;
public void getI(){
}
static void print(){
System.out.println("hi");
};
}
}
public class Test40 {
public static void main(String[] args) {
int j = Temp.i;
Temp t = new Temp();
t.func();
Temp.print();
Temp.Temp2.print();
}
}// static 멤버는 클래스명. 심볼 형태로 접근 >> 결과 : hi 100 hi
-static 멤버 함수 안에서는 non-static한 멤버 함수, 멤버 변수에 접근 할 수 없다 (메모리에 아직 안올라와 있기 때문에)
-abstract 클래스는 인스턴스를 생성할 수 없다.
복습
- class
- instance
- 로컬변수 함수가 호출될 때 메모리할당
- 멤버변수 클래스내에 선언된 변수 인스턴스가 생성될떄 메모리 할당(static이 아닌경우)
- 매개변수 일종의 로컬변수로 함수호출시 생성
- 참조형변수 인스턴스를 가리키기위한 용도 : class 이름으로 선언
- 자료형변수 byte short int long float double boolean char
- 생성자함수 인스턴스가 생성될떄 호출 되는 함수, 주로 멤버변수를 초기화하는데 사용
- extends 인터페이스 외 클래스 상속 1개만가능
- implements 인터페이스 상속
- interface(abstract만 가지고 있는 클래스)
- abstract class(하나의 abstract method가 있는경우 무조건)
- abstract method(선언은 되었지만 구현은 없는경우)
- overriding( 부모로부터 상속)
- overloading( 같은 이름의 메소드 다른 매개변수)
- 자료형변수_캐스팅 : 큰 형태에서 작은형태 x 작은 형태에서 큰형태 o
- 참조형 변수_캐스팅 (큰박스가 작은박스를 감싸는 모양)
- 자료형 변수의 대입 : 오른쪽의 값을 복사해서 왼쪽에 대입
- 참조형 변수의 대입 : 오른쪽이 가리키는 대상이왼쪽을 가리킴
- private : 나만쓸수있음
- public : 나쓸수있고 참조형변수도되고 자손도가능
- protected : 나쓸수있고 자손도가능
- friendly(default) : 같은패키지에서는 public 다른패키지에서는 private
- A t = new B() 조상의 참조형 변수로 자손을 만드는것은 가능하고, 조상의 함수를 호출한 경우 자손의 함수가 호출되므로 오버라이딩 된 구현부가 호출이됨
2. 자바 배열
public class Test5{
public static void main(String[] args){
int[] i = new int[]{1,2,3,4}; //new 사용했으므로 자바의 배열은 인스턴스
//int[] i = {1,2,3,4}로 축약해서 사용할 수 있다.
for(int j : i){ //i = 참조형 변수
System.out.println(j);
}
System.out.println(i.length); //그래서 멤버 변수를 가지고 있음
}
}//배열 : 동일한 형태의 기억장소가 연속으로 할당된 기억공간 >>>결과 : 1 2 3 4 4
for문 구현할 시에는
for(int j = 0; j < i.length; j++){
if(j == 2){
break; //break는 반복문 탈출 , continue는 이하의 코드는 수행을 건너 뛰고 반복을 계속
}
System.out.println(i);
}
3. Object class
-자바의 기본적으로 제공되는 클래스
-자바,lang 패키지에 소속된 클래스는 import 없이 사용 가능
public class Test048 {
public static void main(String[] args) {
Object t = new Temp();
System.out.println(t.toString());// toString()은 Object에 선언되었고, 상속되었다.
Object t2 = new Temp();
System.out.println(t2.toString());
}
}>>결과값 : Temp@460141958 Temp@1163157884
-조상 클래스를 지정하지 않으면 object로부터 상속받는다
-object는 모든 클래스의 조상
-object는 어떤 타입의 인스턴스도 가르킬 수 있다.
-toString()은 오브젝트.클래스에 선언되어 있다.
4. Getter Setter
-멤버 함수는 private 권장 / 값을 읽을 때는 getter함수 제작
-인스턴스 내 변수값 일기 전용 -> getter만 만듬
-인스턴스 내 변수값 바꾸고 싶을 때는 -> setter를 쓰는 것
class Temp{
private Object data = null;
public Object getData(){
return data;
}
public void setData(Object obj){
this.data = obj;
}
}//오브젝트 클래스 getter / setter
주의점
class Temp{
private int data = 100;
public int getData(){
return data;
}
}
class Temp2 extends Temp{
private int data = 200;
public int getData(){
return data;
}
}
public class Test048 {
public static void main(String[] args) {
Temp t = new Temp();
System.out.println(t.getData());
Temp t2 = new Temp2();
System.out.println(t2.getData());
Temp2 t3 = new Temp2();
System.out.println(t3.getData());
}
}//결과값 : 100 200 200
5. String 클래스
-StringPool : 자바에서 String클래스를 유일하게 new 없이 ""로 인스턴스 가능
public class Test048 {
public static void main(String[] args) {
String t = "HelloWorld";
String t2 = "HelloWorld";
System.out.println(t == t2);
System.out.println(t.equals(t2));
System.out.println(t.hashCode());
System.out.println(t2.hashCode());
}//>>결과값 : true true 439329280 439329280
-""를 만나면 VM은 StringPool을 뒤져서 없으면 만들고, 있으면 재활용
-HTML 내용을 String으로 만들고 재활용 하는 쪽이 메모리 관리에 유용하다
-String으로 캐스팅
class Temp{
private Object data = null;
public Object getData(){
return data;
}
public void setData(Object obj){
this.data = obj;
}
}
class Temp2{
private String data = null;
public String getData(){
return data;
}
public void setData(String obj){
this.data = obj;
}
}
public class Test048 {
public static void main(String[] args) {
Temp2 t2 = new Temp2();
t2.setData("HelloWorld"); //스트링만 인스턴스로 저장 할 수 있음 (스트링은 상속불가)
String l2 = t2.getData(); //casting 불필요
Temp t = new Temp();
t.setData("HelloWorld"); //모든 인스턴스로 저장할 수 있음
String l = (String) t.getData(); //캐스팅 필요
}
}
6. Generic : 인스턴스 내부의 자료형을 동적으로 지정할 수 있음.
- Object + 구체적 자료형 결합
-< > 안에 지정 가능한 타입은 참조형 변수 타입이어야 한다.(자료형 안됨)
- System.out.print로 호출하면 자동으로 toString이 호출되도록 약속되어 있다.
class Temp< T extends Object>{
private T data = null;
public T getData(){return data;}
public void setData(T data){this.data = data;}
}
public class Test048 {
public static void main(String[] args) {
Temp<String> t = new Temp<String>();//참조형 변수만 가능, String, integer, double
t.setData("HelloWorld");
System.out.println(t.getData());
Temp<Object> t2 = new Temp<Object>();
t2.setData("HelloWorld");
String l2 = (String) t2.getData();
System.out.println(t2.getData());
}
}//>> 결과값 : HelloWorld HelloWorld
-Integer : int 클래스
-Double : double 클래스 있음
public class Test054 {
public static void main(String[] args) {
Object ob = new Integer(100);
Object ob2 = new Double(3.14);
int i = ((Integer) ob).intValue();
//왜 ? 함수 호출을(Integer)ob는 toString으로 String값이 넘어옴
System.out.println(i);
double j = ((Double)ob2).doubleValue();
System.out.println(j);
}
}
7. AutoBoxing
Integer i = 100;
Object t = 200; //object 변수에서도 autoboxing 동작함 , JDK 1.5에서 추가
System.out.println(i.getClass().getName());
System.out.println(t.getClass().getName());
//결과값 : java.lang.Integer java.lang.Integer
-Integer i = 100; => Integer i = new Integer(100); 로 컴파일러가 자동으로 바꿔줌
-값을 wrapper 클래스에 대입하는 코드는 자동으로 인스턴스 생성하여 값을 감싸줌 : Auto boxing
8.AutoUnboxing
Integer i = 100; //Integer i = new Integer(100);로 자동 줄바꿈
int j = i; //i.intValue();
System.out.println(j);//>> 결과 100
Object t = 200;
int k = t; //error => object타입으로 오토박싱된 인스턴스는 언박싱되지 않는다
//t.intValue()로 호출할 수 없다 -> JDK 1.5에서 추가됨
#근데 공부하다 보니 캐스팅과 박싱의 차이는 뭘까가 궁금해짐
-캐스팅은 단순히 타입 a -> 타입 b
-박싱은 원시 타입(boolean, char) -> 참조 타입(string, file)
-char 주워담아서 박싱하면 스트링 되고 , 스트링 박스를 언박싱하면 char가 된다
9. Command Pattern
interface ICalc{
public int execute(int i);
}
class AddCalc implements ICalc{
private int data;
public AddCalc(int data) {
this.data = data;
}
@Override
public int execute(int i) {
return i+data;
}
}
//쓰임 당하는 입장에서 쓰는 쪽에게 어떤 의견 제시하는 통로 필요 : 어노테이션
// 이것을 체계화 한 것이 1,5 이후에 도입된 Annotation 개념이 된다.
interface PrintStarts{} //어노테이션 인터페이스의 조상뻘 개념
class MinusCalc implements ICalc, PrintStarts{
private int data;
public MinusCalc(int data) {
this.data = data;
}
@Override
public int execute(int i) {
return i-data;
}
}
public class Test054 {
public static void main(String[] args) {
ICalc i = new AddCalc(3);
int r = 5;
r = i.execute(r);
System.out.println(r);
ICalc[] ls = new ICalc[5];
ls[0] = new AddCalc(2);
ls[1] = new MinusCalc(3);
ls[2] = new AddCalc(6);
ls[3] = new MinusCalc(1);
ls[4] = new AddCalc(7);
int y = 10;
for (int j = 0; j < ls.length; j++) {
y = ls[j].execute(y);
if(ls[j]instanceof PrintStarts){
System.out.print("**");
}
System.out.println(y);
}
}
}
/*
일반적으로 자료값은 변수로, 동작은 함수로 만든다.
동작을 하나의 인스턴스로 수행하게 하는 경우가 있다.
- 이런 설계기법을 Command Pattern이라고 한다.
리스트같은데 인스턴스들을 저장하여 매크로처럼 사용 할 수 있다.
*/
10. Build
class Temp1{
int data = 0;
// 아래 코드의 t와 this가 가리키는 대상은 같다.
// 따라서 t.add(10)은 10을 더한 후에 t로 바꿔 쓸 수 있다.
// StringBuffer의 append에서 볼 수 있다.
Temp1 add (int i){
data += i;
return this;
}
}
public class Test057 {
public static void main(String[] args) {
Temp1 t = new Temp1();
t.add(10).add(10).add(100);
System.out.println(t.data);
}
}//결과 : 120
11. String Buffer Class
public class Test057 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("apple");
sb.append("banana");
String l = sb.toString();
System.out.println(l);
System.out.println("apple" + "banana");
//코드는 컴파일러가 new StringBuffer().append("apple").append("banana").toString
//방식으로 한줄마다 new StringBuffer가 동작하지만 위의 코드는 한번만 동작
}
}//applebanana applebanana
12.String vs StringBuffer Test
public class Test057 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 100000; i++) {
sb.append("apple");
}//StringBuffer : 하나의 인스턴스
long end = System.currentTimeMillis();
System.out.println(end - start);
start = System.currentTimeMillis();
String st = new String("");
for (int i = 0; i < 100000; i++) {
st += "apple";
}//String : 다수의 인스턴스
end = System.currentTimeMillis();
System.out.println(end - start);
}
}//결과값 : 8 11645 //StringBuffer가 훨씬 좋음
-java -verbosegc 클래스 이름 통해 가비지 콜렉터 과정을 볼 수 있음
-메모리가 부족할 때 메모리를 비우고 확보하는 일 모니터링
13.String
-SubString();
String l = "HelloWorld";
System.out.println(l.substring(2,5)); //llo
-indexOf(); : 만약 없는 문자열 찾을 때는 -1 리턴/ 문자열 안의 부분 문자열 위치를 리턴
String l = "HelloWorld";
System.out.println(l.indexOf("or")); //>>6
-starsWidth(); / endsWidth(); 시작이나 끝 문자열이 매개변수값과 같으면 true 아니면 false
String l = "HelloWorld";
System.out.println(l.startsWith("Hell"));
System.out.println(l.endsWith("ld")); //true true
-toCharArray(); : String을 char 배열로
String l = "HelloWorld";
char[] ch = l.toCharArray();
for (int i = 0; i < ch.length; i++) {
System.out.println(ch[i]);
}//결과값 : H e l l o W o r l d
문제
배열의 최대값 구하기
public class Test045 {
public static void main(String[] args) {
int[] i = new int[]{4,9,6,5};
int max = i[0];
for (int j = 1; j < i.length; j++) {
if(max < i[j]){
max = i[j];
}
}
System.out.println(max);
}
}//>>9
제너릭 연결리스트
package node;
class Node<T>{
T data = null;
Node<T> next = null;
Node(T i, Node<T> n){
data = i;
next = n;
}
}
class LinkedList<X>{
private Node<X> head = null;
private Node<X> tail = null;
public LinkedList() {
this.head = new Node<>(null, null);
this.tail = head;
}
public LinkedList<X> add(X input){
tail.next = new Node<>(input, null);
tail = tail.next;
return this;
}
public void print(){
for(Node<X> n = head.next; n != null; n = n.next){
System.out.println(n.data);
}
}
}
public class MyLinkedList {
public static void main(String[] args) {
LinkedList<String> ll= new LinkedList<>();
ll.add("test").add("this").add("how");
ll.print();
LinkedList<Integer> l2 = new LinkedList<>();
l2.add(3).add(2);
l2.print();
}
}
String의 indexOf와 동일한 동작 하게
package index;
class Finder{
public static int indexOf(char[] operand, char[] operator) {
int odLenth = operand.length;
int otLenth = operator.length;
int idx = -1;
for (int remainder = odLenth - otLenth; remainder >= 0; remainder--) {
if(operand[remainder] == operator[0]){
for(int i=1; otLenth-1 >= i; i++){
if(operand[remainder+i] == operator[i]){
if(i == otLenth-1){
idx = remainder;
break;
}
}else {
break;
}
}
}
}
return idx;
}
}
public class MyIndexOf {
public static void main(String[] args) {
int idx = Finder.indexOf("Hedoerrdwld".toCharArray(), "sdadsadsadorw".toCharArray());
System.out.println(idx);
}
}
Day 5
1. Casting : instanceOf 키워드를 이용해서 알 수 있다.
-Casting Error : t가 가르키고있는 B라는 인스턴스가 존재해야만 캐스팅이 가능해짐
class A{
}
class B extends A {
public void print() {
System.out.println(100);
}
}
public class Test061 {
public static void main(String[] args) {
A t= new A();
if*
B t2 = (B) t;
t2.print();
}
}
//결과값 : Exception in thread "main" java.lang.ClassCastException:
javaclass.A cannot be cast to javaclass.B at javaclass.Test061.main(Test061.java:16)
-instanceof : 캐스팅 에러 미리 방지
A t= new A();
//(B)t 이것이 가능하면 true/ 아니면 false
if (t instanceof B){
B t2 = (B) t;
t2.print();
}
-boolean : 비교연산 값을 리턴
-거의 모든 연산은 같은 자료형 끼리 가능
-double간의 연산 비교는 정확하지 않는다.
public class Test061 {
public static void main(String[] args) {
boolean i = true;
boolean j = false;
System.out.println(10 < 5);
System.out.println(10 / 3); // 나머지를 뺀 몫이 나옴
System.out.println(10 % 3); //나머지를 구하는 연산자
System.out.println(10.0 / 3);
System.out.println(3.33333333 * 3 == 10.0);
System.out.println(3.3333333333333335 * 3== 10.0); //Double 연산은 값을 보장할 수없다. 오차발생
}// c는 정수값 0 은 false, 0이아닌 모든 정수는 true
}// if(100)참
//결과값 : false 3 1 3.3333333333333335 false true
2.Package
-클래스의 묶음, 파인 맨 위에 지정
-한 파일안에 선언한 모든 클래스는 지정된 패키지 속함
-패키지를 지정하지 않으면 Unnamed 패키지에 소속, 사용시 제약이 많음
- javac -d . Test061.java
대상폴더아래 패키지이름으로 폴더생기고, 그 아래에 class파일이 들어간다.
package javaclass;
public class Test061 {
public int print(){
return 200;
}
public int print2(int i ){
return 300 * i;
}
public static int print3(){
return 100;
}// 패키지가 지정된 클래스 컴파일 : javac -d [폴더위치] Test061.java
}
3.import
-다른 패키지 클래스는 반드시 명시
-만일 그래도 못찾으면 class 를 명시해야한다.
javac -classpath C:\A\ Test061.java
-실행 : java -classpath .;C:\A\ Test061
-> 현재 폴더 명시해줘야함
-classpath 옵션을 안주면 -classpath . 이 자동으로 붙는다.
-Test 061A의 멤버변수가 접근되는지 살펴본다 : protected, friendly(default) -> 다른패키지에서 접근 x
-Static한건 클래스가 로딩될떄 메모리에 할당 non-Static한건 인스턴스가 생성될떄 메모리에 할당
-클래스로딩은 딱 한번만일어나므로 Static한건 딱 한개만 존재함
-Static Initializer: 클래스가 로딩되는 시점에 실행되고 클래스를 강제로 로딩하려면 Class.forName("클래스명");함수를 이용한다.
package practice;
import javaclass.Test061;
public class Test064 {
public static void main(String[] args) {
Test061 t = new Test061();
t.print();
}
}
package temp;
public class Test066A{
//static initializer라 한다. 클래스가 로딩되는 시점에 호출됩니다.
static{
System.out.println("Test066A loaded");
}
public int print(){return 200;}
public int print2(int i){return 300*i;}
public static int print3(){return 100;}
} // C:\a\ 아래에 컴파일하자. javac -d c:\A\ Test066A.java
public class Test066{
public static void main(String[] args) throws Exception{
//클래스를 찾아내서 해당 클래스를 강제로 메모리에 로딩시킨다.
//찾아낸 코드의 static initializer가 동작하게됨
Class<?> cls = Class.forName("temp.Test066A");
/* Class : 로딩된 클래스의 관리자 역할을한다.
cls.newInstance() : cls가 관리하는 temp.Test066A의 인스턴스를 생성한다.
obj.getClass().getName() : obj가 가리키는 인스턴스를 생성시킨 클래스 명 //임포트없이도 다른 패 키지의 인스턴스를 생성 할 수 있음
*/
Object obj = cls.newInstance(); //new를 쓰지않고 인스턴스를 만드는방법
System.out.println( obj.getClass().getName());
}
}
import java.lang.reflect.Method;
public class Test066_2{
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("temp.Test066A");
Object obj = cls.newInstance();
/* getMethods() : 클래스안에서 선언된 함수에 대한 포인터들을 추출한다.
*/
Method[] mtds = cls.getMethods(); //함수 포인터
for (int i = 0; i < mtds.length; i++) {
System.out.println(mtds[i]);
}
}
}
/*결과값 : Test066A loaded
public int temp.Test066A.print()
public int temp.Test066A.print2(int)
public static int temp.Test066A.print3()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()*/
package javaclass;
import java.lang.reflect.Method;
public class Test066_3 {
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("temp.Test066A");
Object obj = cls.newInstance();
// Method는 C의 함수포인터의 역할을 한다.
// cls.getMethods()는 모든 멤버함수의 포인터를 넘긴다.
// cls.getMethod(...) : 단하나의 멤버함수의 포인터를 넘기다.
// ...에는 함수이름, 매개뱐수의 형태를 명시한다.
// Method mtd = cls.getMethod("print");
Method mtd = cls.getMethod("print2", int.class);
System.out.println(mtd);
Object r = mtd.invoke(obj, 20);
System.out.println(((Integer)r).intValue());
}
}
/*결과값 : Test066A loaded
public int temp.Test066A.print2(int)
6000*/
package javaclass;
import java.lang.reflect.Method;
public class Test066_3 {
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("temp.Test066A");
// Object obj = cls.newInstance();
// Method는 C의 함수포인터의 역할을 한다.
// cls.getMethods()는 모든 멤버함수의 포인터를 넘긴다.
// cls.getMethod(...) : 단하나의 멤버함수의 포인터를 넘기다.
// ...에는 함수이름, 매개뱐수의 형태를 명시한다.
// Method mtd = cls.getMethod("print");
Method mtd = cls.getMethod("print3");
System.out.println(mtd);
Object r = mtd.invoke(cls);
System.out.println(((Integer)r).intValue());
}
}
/*결과값 : Test066A loaded
public static int temp.Test066A.print3()
100*/
4.annotation
- 클래스나 method에 붙임
- 클래스가 컴파일되거나 런될때, annotation의 유무나 annotation 설정된 값을 통하여 클래스가 좀더 다르게 실행
- 설정파일처럼 설정하는 경우도
- 사용자 annotation
- annotation 정의
- annotation를 class에서 사용
- annotation을 이용해 실행
package temp;
public class Test067 {
@PrintStars
public int print(){
return 100;
}
}// javac -d C:\a\ -classpath C;\A\ Test067.java -> import할 파일 위치
-----------------------------------------------------------------------------------
package temp;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface PrintStars {
}
-----------------------------------------------------------------------------------
package javaclass;
import temp.PrintStars;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class Test067_2 {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("temp.Test067");
Object obj = cls.newInstance();
Method mtd = cls.getMethod("print");
Annotation anot = mtd.getAnnotation(PrintStars.class);
Object r= mtd.invoke(obj);
if(anot.toString().equals("@temp.PrintStars()")){
System.out.println("**");
}
System.out.println(((Integer)r).intValue());
System.out.println(anot);
System.out.println(mtd);
}
}// javac Test067_2.java 컴파일시
//java -classpath C:\A\;. Test067_2 //내가 실행시킬 위치는 뒤 불러올거는 클래스패스 뒤, 여러개 불러올거면 ;로구분
/*결과값 : **
100
@temp.PrintStars()
public int temp.Test067.print()*/
5.java.util.*
-List
- arraylist : 내부 배열 이용 , 속도 빠름, 중간 삭제 수정 힘듬
- LinkedList : node 이용, 속도 느림, 중간 삭제 수정 쉬움(포인터만 바꿔주면됨)
- list 특징 : 1. 중복 허용 2. 순서 유 3. stack, queue 유용
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
//ArrayList 속도가 빠르다. 내부적으로 배열을 사용
//배열을 사용하기때문에 속도는 빠른데, 중간중간 삭제가일어나면 비효율적이다.
//LinkedList Node를 이용하기에 단순하게 쌓는 속도는 느리다.
//중간에 추가 삭제가 빈번한 경우에는 용이하다.
// 둘 다 List를 상속한다. List를 상속받은 클래스는 특징이 존재한다.
// - 중복되는 걸 허용한다.검색시에 들어간 순서대로 나온다.(순서대로 보관한다.)->스택이나 큐 만드는데 용이하다.
public class Test068 {
public static void main(String[] args) {
List<String> l = new LinkedList<>();
l.add("apple");
l.add("banana");
l.add("orange");
l.add("kiwi");
for (String t : l) {
System.out.println(t);
}
}
}//결과값 : apple banana orange kiwi
-Set
- treeset : 트리를 이용해 검색 속도가 list보다 월등
- hastset : 해쉬 알고리즘을 이용해 기억 장소 할당
- set 특징 : 1. 중복 허용 x 2.순서 x
package javaclass;
import java.util.Set;
import java.util.TreeSet;
// Set 인터페이스를 상속받은 것 : TreeSet, HashSet
// 공통특징 : 순서 개념이 없다. 중복을 허용하지 않는다.
// 저장할때 용이 -> 검색속도가 List보다 월등함
// TreeSet : 트리를 이용하여 보관, HashSet은 Hash알고리즘을 이용
public class Test069 {
public static void main(String[] args) {
Set<String> l = new TreeSet<>();
l.add("apple");
l.add("banana");
l.add("orange");
l.add("kiwi");
l.add("apple"); //중복된값
for (String t : l) {
System.out.println(t);
}
}
//결과값 : banana orange apple kiwi
-향상된 for문의 표준 검색 방법
Iterator<String> it = l.iterator();
while (it.hasNext()) {
String next = it.next();
System.out.println(next);
}
//iterator를 이용한 삭제
package javaclass;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
// Set 인터페이스를 상속받은 것 : TreeSet, HashSet
// 공통특징 : 순서 개념이 없다. 중복을 허용하지 않는다.
// 저장할때 용이 -> 검색속도가 List보다 월등함
// TreeSet : 트리를 이용하여 보관, HashSet은 Hash알고리즘을 이용
public class Test069 {
public static void main(String[] args) {
Set<String> l = new HashSet<>();
l.add("apple");
l.add("banana");
l.add("orange");
l.add("kiwi");
l.add("apple"); //중복된값
Iterator<String> it = l.iterator();
while (it.hasNext()) {
String next = it.next();
if(next.indexOf("an") != -1){
it.remove();
}
System.out.println(next);
}
}
}
-Map
- map 특징 : 1.순서 x 2.중복 x(덧 씌워짐)
package javaclass;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
//map도 순서개념이 없으며 반드시 key = value 형태로 저장되야함 사전과 같은 형태
//put에 함수로 저장, get 함수로 key에 해당하ㅏ는 value를 뽑아낸다.
//list, Set, Map 형태로 뭔가 저장하는 형태를 흔히 Collection이라고 한다.
public class Test070 {
public static void main(String[] args) {
Map<String, String> map = new Hashtable<>();
map.put("apple", "사과");
map.put("banana", "바나나") ;
map.put("orange", "오렌지") ;
map.put("kiwi", "키위") ;
map.put("banana", "브내으너") ;
String value = map.get("apple");
System.out.println(value);
Set<String> keys = map.keySet();
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
String next = it.next();
String v = map.get(next);
System.out.println(next+ ", " + v);
}
System.out.println(map);
}
}/*
결과값 : 사과
banana, 브내으너
apple, 사과
orange, 오렌지
kiwi, 키위
{banana=브내으너, apple=사과, orange=오렌지, kiwi=키위}
*/
-Math.random();
package javaclass;
public class Test071 {
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
double d = Math.random(); // 0부터 1까지의 소수값을 랜덤하게 출력한다.
int a = (int) (d * 100); // 0~100까지
System.out.println(a);
}
}
}
-Throw
-각종 에러는 클래스로 구형
-코드 수행시 에러가 발생하면 해당 예외클래스의 인스턴스를 throw해버린다
-예외는 함수 수행 시에 발생되고, 함수에 그 사실을 명시
-생성된 예의처리 못할 시 프로그램 종료
package javaclass;
class TempException extends RuntimeException{}
public class Test074{
public static void main(String[] args) {
int i = 0;
if(i==0){
throw new TempException();
}
System.out.println(0);
}
}
package javaclass;
//연료 고갈이라는 에러를 클래스로 명시
class FuelException extends Exception{}
// Exception이 깐깐하다 : 컴파일이 안된다....
// 함수 안에서 에러가 발생 할 수 있다면 그 사실을 선언부에 명시해야 컴파일된다.
public class Test074{
public void carDrive(int fuel) throws FuelException{ //thorws로 연료고갈이 생길수 있음을 명시
if(fuel == 0){
throw new FuelException();
}
System.out.println("gogo");
}
public static void main(String[] args) {
Test074 t = new Test074();
//throws FuelException으로 선언된 함수를 호출할 때는 반드시 에러가 발생할 수 이는 영역을 try{...}로 감싸준다.
//try에는 반드시 1개이상의 catch가 있어야한다.
//에러가 발생되면 에러 인스턴스를 throw한다.
//catch(FuelException e)에 있는 e 변수가 발생된 에러 인스턴스를 가리 킬 수 있으면 catch에 딸린{...} 영역이 동작한다.
//...에는 에러를 수습 할 수 있는 코드가 들어가는것이 바람직하다.
//catch (Exception e)써도 됨 상속받기 떄문에
try {
t.carDrive(100);
} catch (FuelException e) {
System.out.println("견인차를 불러라");
}
}
}
package javaclass;
class FuelException extends Exception{
public void solve(){
System.out.println("견인차를 불러라");
//에러 처리
}
}
public class Test074{
public void carDrive(int fuel) throws FuelException{
if(fuel == 0){
throw new FuelException();
}
System.out.println("gogo");
}
public static void main(String[] args) {
Test074 t = new Test074();
try {
t.carDrive(100);
} catch (FuelException e) {
e.solve();
}
}
}
문제
1. 복권 뽑기 1
public static int[] randomArray(int i, int max) {
Set<Integer> si = new HashSet<>();
while(si.size() < i){
si.add((int)(Math.random()* max));
}
Object[] arr = si.toArray();
int[] result = new int[i];
int start = 0;
for(Object obj : arr){
result[start] = (int) obj;
start++;
}
return result;
}
2. 복권 뽑기2
public static int[] randomArray2(int i, int max){
int[] total = new int[max+1];
int[] result = new int[i];
for (int j = 0; j <= max; j++) {
total[j] = 0;
}
int counter =0;
while (counter < i) {
int rand = (int) (Math.random() * max);
if(total[rand] == 0){
result[counter] = rand;
counter ++;
total[rand] = 1;
}
}
return result;
}
3.리스트 출력
public static String collectionString(List<String> ls) {
String result;
if(ls.isEmpty()){
return "[]";
}else {
StringBuilder sb = new StringBuilder();
sb.append("[");
int start= 1;
int end = ls.size();
for(String t : ls){
sb.append("'");
sb.append(t);
sb.append("'");
if(start == 1 && end ==1){
start++;
continue;
}
start++;
if(start > end) {
break;
}else {
sb.append(",");
}
}
sb.append("]");
result = sb.toString();
}
return result;
}
}
// 2가지 이상의 다른 방법으로 구현 1가지는 collection 금지
public class Test072_HW {
public static void main(String[] args) {
int[] rl = HW.randomArray2(10, 100);
for (int i = 0; i < rl.length; i++) {
System.out.println(rl[i]);
}
List<String> ls = new ArrayList<>();
ls.add("apple");
ls.add("banana");
ls.add("orange");
ls.add("kiwi");
String l = HW.collectionString(ls);
System.out.println(l);
}
}
첫 주 끝.. 알고리즘 꼭 다시 풀어보기 / 자동차 패키지 만들어보기 !
'Language Study > Java' 카테고리의 다른 글
제주에서 자바_Week2_2 (0) | 2019.07.24 |
---|---|
제주에서 자바_Week2_1 (0) | 2019.07.22 |
4. 클래스 (0) | 2019.05.29 |
3. 참조 타입 (0) | 2019.05.28 |
2. 조건문 & 반복문 (0) | 2019.05.27 |