IT 면접족보/자바 면접족보

자바 수업 정리 - methods of Arrays class, StringTokenizer, Generic(19 일차)

낙산암 2020. 12. 22. 17:40

 

1. BigInteger 클래스에 대하여 설명하시오.

BigInteger class & BigDecimal class

메모리가 유한하기 때문에 메모리 공간을 절약할 수 있으면서, 속도 면에서도 유리할 수 있게 데이터 타입을 세부적으로 나눠(기본 8가지 타입) 적절한 데이터 타입을 사용하도록 했다.

일반적인 상황, 프로젝트의 경우에는 이 정도로 큰 수는 필요하지 않다. 하지만 예를 들면 수학이나 과학 분야 등에서 더 크거나 정밀한 수가 필요한 경우(지정된 8개 타입으로 표현할 수 없는 경우)에 BigInteger, BigDecimal class를 사용한다. 두 클래스는 꼭 필요한 경우에만 제한적으로 사용 해야하며 무조건적으로 사용하는 것은 지양 해야 한다.

  • 이 클래스들을 기반으로 만들어진 인스턴스는 immutable이다! (연산 결과 → 새로운 객체 생성)

  • 문자열로 인자를 받아서 함수로 연산한다.

  • 클래스 안에는 우리가 생각하는 쓸만한 데이터 멤버, 함수들이 많이 포함되어있다.

    .MAX_VALUE, .MIN_VALUE, .add, .multiply 등등

[궁금한 점] 문자열로 받은 숫자를 BigInteger 클래스 함수로 받아서 연산 한다고 했는데, 그럼 연산을 해야하는데, 숫자 타입 값으로 형변환 없이 문자열을 어떻게 연산을 하는 걸까?

 

2. 아래의 결과 값은 false 출력이 된다. true 가 되도록 INum을짜시오.

  INum[] ar1 = new INum[3];
  INum[] ar2 = new INum[3];

  ar1[0] = new INum(1); ar2[0] = new INum(1);
  ar1[1] = new INum(2); ar2[1] = new INum(2);
  ar1[2] = new INum(3); ar2[2] = new INum(3);

  System.out.println(Arrays.equals(ar1, ar2));

풀이

key INum 클래스에서 equals 함수 Override

 

import java.util.Arrays;

class INum {
	int num;
	
	public INum(int num) {
		this.num = num;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this.num == ((INum)obj).num)
			return true;
		else
			return false;
	} 
}

public class INumMain {
	public static void main(String[] args) {
		INum[] ar1 = new INum[3];
		INum[] ar2 = new INum[3];
		
		ar1[0] = new INum(1);
		ar2[0] = new INum(1);
		ar1[1] = new INum(2);
		ar2[1] = new INum(2);
		ar1[2] = new INum(3);
		ar2[2] = new INum(3);
		
		System.out.println(Arrays.equals(ar1, ar2));
	}
}

3. 아래에서 정렬이 이름 순으로 되게끔 하시오. Person 객체를 만드시오.

class ArrayObjSearch {
	public static void main(String[] args) {

		Person[] ar = new Person[3];    
		ar[0] = new Person("Lee", 29);
    ar[1] = new Person("Goo", 15);
    ar[2] = new Person("Soo", 37);

    Arrays.sort(ar);
	}
}
import java.util.Arrays;

class Person implements Comparable {
	String name;
	int age;
	
	Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	
	@Override
	public String toString() {
		return name + ": " + age;
	}
	
	@Override
	public int compareTo(Object o) {
		Person p = (Person)o;
		int cmp = (this.name).compareTo(p.name);  // String함수 comparTo 함수 사용
		if(cmp > 0 )
			return 1;
		else if (cmp < 0)
			return -1;
		else
			return 0;
	}
	
public class ArrayObjSearch {
	public static void main(String[] args) {
		Person[] ar = new Person[3];
		
		ar[0] = new Person("Lee", 29);
		ar[1] = new Person("Goo", 15);
		ar[2] = new Person("Soo", 37);

		Arrays.sort(ar);
		
		for(Person n : ar)
			System.out.print(n + " \t");
		System.out.println();
	}
}

/*
	출력 결과
	Goo: 15 	Lee: 29 	Soo: 37
*/
  1. compareTo 함수 override위해 implements Comparable (interface)

  2. Peson 클래스에서 compareTo 함수 override : 사전 배열 순서로 정렬 될 수 있도록 구현부를 재정의함

→ 이름의 문자열을 사전 배열 순서 기준으로 정리하기 위해 String 함수에 override되어있는 comareTo함수를 불러 와서 사용했다.

  1. Person 클래스에서 toString 함수 override: Person의 객체를 println 인자로 받을 때 문자열로 출력될 수 있도록 재정의

4. 위의 문제에서 사람의 이름 글자 수가 많은 순으로 정렬을 되게끔 person 객체를 만드시오.

import java.util.Arrays;

class Person implements Comparable {
	String name;
	int age;
	
	Person(String name, int age){
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return name + ": " + age;
	}
	
	@Override
	public int compareTo(Object o) {
		Person p = (Person)o;
		if(this.name.length() > p.name.length()) //자신 글자수가 많으면 음의 정수 리턴 
			return -1;
		else if(this.name.length() < p.name.length()) //자신 글자수가 적으면 양의 정수 리턴 
			return 1;
		else
			return 0;  //자신과 전달받은 o의 글자수 같으면 0 리턴
	}
}

public class ArrayObjSearch {
	public static void main(String[] args) {
		Person[] ar = new Person[3];
		
		ar[0] = new Person("Lee Sumin", 29);
		ar[1] = new Person("Go Yumi", 15);
		ar[2] = new Person("Soo", 37);

		Arrays.sort(ar);
		
		for(Person n : ar)
			System.out.print(n + " \t");
		System.out.println();
	}
}

/*
출력 결과
Lee Sumin: 29 	Go Yumi: 15 	Soo: 37
*/

5. 경과 시간을 맞추는 게임을 작성하라.

10초에 가까운 사람이 이기는 게임입니다.
황기태 시작 키  >>
현재 초 시간 = 42
10초 예상 후 키  >>
현재 초 시간 = 50
이재문 시작 키  >>
현재 초 시간 = 51
10초 예상 후 키  >>
현재 초 시간 = 4
황기태의 결과 8, 이재문의 결과 13, 승자는 황기태

다음 예시를 참고하면, <Enter> 키를 입력하면 현재 초 시간을 보여주고 여기서 10초에 더 근접하도록 다음 <Enter> 키를 입력한 사람이 이기는 게임이다.

 

class Person {
	Calendar now = Calendar.getInstance();
	Scanner sc = new Scanner(System.in);
	private String name, buffer;
	private int sec1, sec2;
	
	public Person(String name) {
		this.name = name;
	}
	
	public int game() {
		System.out.print(name+" 시작 <Enter>키  >>");
		sec1 = enter();
		System.out.print("10초 예상 후 <Enter>키  >>");
		sec2 = enter();
		if(sec1 < sec2)
			return sec2-sec1;
		else 
			return (60-sec1) + sec2;
	}
	
	public int enter() {
		buffer = sc.nextLine();
		now = Calendar.getInstance();		
		System.out.println("\t현재 초 시간 = "+ now.get(Calendar.SECOND));
		return now.get(Calendar.SECOND);
	}
}
public class chap06_prac06 {
	public static void main(String[] args) {
		Person person1 = new Person("황기태");
		Person person2 = new Person("이재문");
		
		System.out.println("10초에 가까운 사람이 이기는 게임입니다.");
		int result1 = person1.game();
		int result2 = person2.game();
		
		if(Math.abs(result1 - 10) < Math.abs(result2 - 10))
			System.out.println("황기태의 결과 "+result1+", 이재문의 결과 "+result2+", 승자는 황기태");
		else
			System.out.println("황기태의 결과 "+result1+", 이재문의 결과 "+result2+", 승자는 이재문");
	}
}

6. 지네릭(Generic)이란?

 

  • Java 1.5 부터 나온 개념 : Generic이 나오기 전까지는 참조형 변수 타입을 Object로 받을 수 밖에 없었다.

  • 기능: 자료형을 결정짓지 않고 틀을 만들어 두는 것을 말함 (c++에서는 템플릿 이라고 함)

  • 형태: Object(참조형 타입) 자리에 T들어감 → Generic

    그래서 자료형의 정보를 Object 대신 T로 작성해 비워 두고 인스턴스 생성시 참조 타입을 결정

  • 등장 배경: Generic이전의 코드에서 Object로 참조 변수를 선언했을 때 발생하는 문제들을 Generic을 사용함으로써 컴파일 단계에서 잡아줄 수 있도록 했음

    예시 코드 기준으로 설명하면

    1. Apple ap = (Apple)aBox.get();와 같이 프로그래머가 명시적 형변환을 해서 책임을 지게 만들지 않고, 컴파일러가 체크해서 코드의 안정성이 떨어지는 문제를 해결할 수 있도록 함
    2. aBox.set("Apple"); 와 같은 상황에서 컴파일러가 체크하지 못해서 실시간 에러로 이어지는 문제도 컴파일 에러로 잡을 수 있게 됨
    3. System.out.println(aBox.get()); 와 같이 말도 안되는 상황에서 어떤 에러도 발생하지 않고 심지어 그게 실행이 되는 가장 큰 문제 상황을 컴파일 에러로 막아 줄 수 있게 됨!

Generic 이전의 코드의 문제 상황들

오류의 발견 (예제 코드에서 자세한 설명)

  1. 컴파일 과정에서 발견(ok.. 쉽게 수정 가능)
  2. 실행 과정에서 예외로 발견(그나마 나은 상황)
  3. 실수가 실행 과정에서 조차 발견되지 않을 수 있다!!! → 진짜 큰 문제 상황!!!

→ 문법이 컴파일 과정에서 실수가 발견될 수 있도록 발전해 가고 있다. (하지만 공부할 것이 많아짐)

최대한 컴파일 과정에서 오류가 발견될 수 있도록 코드를 짜는 것이 좋은 것!

 

Generic기반 인스턴스 생성

이제는 인스턴스 생성시 타입이 결정되어 아무거나 받을 수 없기 때문에 위에서 본 예제 처럼 의도 하지 않은 타입을 넣었을 때 컴파일되는 등의 오류는 컴파일시에 바로 잡아낼 수 있다!!!!

 

타입매개변수(Type Parameter)       Box<T>에서 T // 타입을 결정한다!
타입인자(Type Argument)           Box<Apple>에서 Apple
매개변수화타입(Parameterized Type)  Box<Apple>

Box<Apple> aBox = new Box<Apple>();
	→ T 를 Apple 로 결정하여 인스턴스 생성
	→ 따라서 Apple 또는 Apple 을 상속하는 하위 클래스의 인스턴스 저장 가능

Box<Orange> oBox = new Box<Orange>();
	→ T 를 Orange 로 결정하여 인스턴스 생성
	→ 따라서 Orange 또는 Orange 를 상속하는 하위 클래스의 인스턴스 저장 가능

실수가 컴파일 오류로 이어짐! (예제 코드)

public static void main(String[] args) {
	Box<Apple> aBox = new Box<Apple>();     //→ 제네릭 객체 생성
	Box<Orange> oBox = new Box<Orange>();   //→ 제네릭 객체 생성
	
	aBox.set("Apple");      // 프로그래머의 실수 → 컴파일 오류로 발견 → 코드 안정성 높아짐
	oBox.set("Orange");     // 프로그래머의 실수 → 컴파일 오류로 발견 → 코드 안정성 높아짐
	
	Apple ap = aBox.get();
	Orangeog = oBox.get();

	System.out.println(ap);
	System.out.println(og);
}

7. 아래를 프로그래밍 하시오.

Rectangle r1 = new Rectangle(5,6);
Rectangle r2 = new Rectangle(7,9);

Rectangle r3 = Rectangle.compareRect(r1,r2);

System.out.println(r3.getHeight() + " : " + r3.getWidth()  + "입니다.");

/*
=============================
출력 : 
9 : 7 입니다.
*/

key : static?

compareRect(r1, r2) 함수 연산의 결과를 r3에 대입

→ 대입을 위해 compareRect 함수는 Rectangle형을 리턴 해야 함

→ 연산의 결과는 area 구한 후(?) 큰 값을 가진 것을 리턴

→ Rectangle.compareRect(r1, r2) → compareRect 함수는 static

class Rectangle {
	private int width;
	private int height;
	
	Rectangle(int width, int height){
		this.width = width;
		this.height = height;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}
	

	public static Rectangle compareRect(Rectangle r1, Rectangle r2) { 
		if(r1.width *  r1.height > r2.width * r2.height)
			return r1;
		else if(r1.width *  r1.height < r2.width * r2.height)
			return r2;
		else 
			return r1;
	}
	
}

public class RecAreaMain {
	public static void main(String[] args) {
		Rectangle r1 = new Rectangle(5,6);
		Rectangle r2 = new Rectangle(7,9);

		Rectangle r3 = Rectangle.compareRect(r1,r2);
		
		System.out.println(r3.getHeight() + " : " + r3.getWidth()  + "입니다.");
	}
}

8. 아래를 프로그래밍 하시오.

 

  • Rectangle 배열 4개를 만든 후 스캐너 객체로 가로와 세로를 입력하여 4개의 객체를 배열에 할당한다
  • getSortingRec 사각형 배열을 내림 차순 정렬한다.
  • 정렬이 제대로 되었는지 배열에 저장된 객체의 getArea()함수를 순서대로 호출한다.
class Rectangle implements Comparable{
    private int width;
    private int heigth;
    
    public Rectangle(int width, int heigth) {
        this.width = width;
        this.heigth = heigth;
    }
    
    public int getArea() {       
       return width * heigth;
    }
   
    @Override
   public int compareTo(Object o) {      
      //return this.getArea() - ((Rectangle)o).getArea();
      return ((Rectangle)o).getArea() - this.getArea()  ;
   }   
}

class RecArrays {  
   public static Rectangle[] sort(Object[] arrRecs) {
      Rectangle[] recs = (Rectangle[])arrRecs;
      Rectangle temp = null;
      
      if(recs instanceof Comparable[]) { //컴페어러블 구현 할 때
         
         for(int i = 0 ; i < recs.length ; i++) {
            for(int j = 0 ; j < recs.length -i -1 ; j ++) {
               
               if(recs[j].compareTo(recs[j+1]) > 0) { //이걸 반드시 써먹어야한다. 
                       temp = recs[j];
                       recs[j] = recs[j + 1];
                       recs[j + 1] = temp;
												//양수이면 자리바꿔서 오름차순으로 하겠다.
               }            
            }
         }         
         
      }else {  //컴페어러블 구현안할때
         for(int i = 0 ; i < recs.length ; i++) {
            for(int j = 0 ; j < recs.length -i -1 ; j ++) {
               if(recs[j].getArea() > recs[j+1].getArea()) {
                       temp = recs[j];
                       recs[j] = recs[j + 1];
                       recs[j + 1] = temp;
               }
            }
         }
         
      }        
      return recs;
   }
}


public class Money {

   public static void main(String[] args) {
        
      Rectangle[] recArr = {new Rectangle(6, 6),new Rectangle(5, 5),new Rectangle(10, 10),new Rectangle(12, 12),new Rectangle(11, 11)};
      
      RecArrays.sort(recArr);
      
      //Arrays.sort(recArr);
      
      System.out.println(recArr.toString());
      
      for ( Rectangle rec: recArr) {
         System.out.println(rec.getArea());
      } 
   }
}

//중요한점
//음수와 양수의 의미
//array.sort를 만들때 개발자에게강제 시킴 컴페어러블 상속받아 저컴페어 투만 정의해라. 
//그럼 위에꺼 호출해주겠다.