Java 정리 - 10 (Set, List, Map, Date, Calendar, java.time 패키지, 자바IO)

Minseol·2022년 8월 9일
0

Java 공부

목록 보기
11/12

Set

set은 중복이 없고, 순서도 없는 자료구조. Hashset과 TreeSet이 있다.

	import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;

    public class SetExam {
        public static void main(String[] args) {
            Set<String> set1 = new HashSet<>();

            boolean flag1 = set1.add("kim");
            boolean flag2 = set1.add("lee");
            boolean flag3 = set1.add("kim");

            System.out.println(set1.size());   //저장된 크기를 출력합니다. 3개를 저장하였지만, 이미 같은 값이 있었기 때문에 2개가 출력
            System.out.println(flag1);  //true
            System.out.println(flag2);  //true
            System.out.println(flag3);  //false

            Iterator<String> iter = set1.iterator();

            while (iter.hasNext()) {   // 꺼낼 것이 있다면 true 리턴.          
                String str = iter.next(); // next()메소드는 하나를 꺼낸다. 하나를 꺼내면 자동으로 다음것을 참조한다.
                System.out.println(str);
            }
        }
    }

HashSet 클래스

Set 인터페이스를 구현한 클래스

멤버의 중복 여부를 체크하기 위해 인스턴스의 동일성을 확인해야 함

동일성 구현을 위해 필요에 따라 equals()와 hashCode()메서드를 재정의함

TreeSet 클래스

객체의 정렬에 사용하는 클래스

Set 인터페이스를 구현하여 중복을 허용하지 않고, 오름차순이나 내림차순으로 객체를 정렬할 수 있음

내부적으로 이진검색트리(binary search tree)로 구현됨

이진검색트리에 저장하기 위해 각 객체를 비교해야 함

비교 대상이 되는 객체에 Comparable이나 Comparator 인터페이스를 구현 해야 TreeSet에 추가 될 수 있음

String, Integer등 JDK의 많은 클래스들이 이미 Comparable을 구현했음

List

list는 데이터의 중복이 있을 수 있고, 순서도 있다.

	import java.util.ArrayList;
    import java.util.List;

    public class ListExam {

        public static void main(String[] args) {
            List<String> list = new ArrayList<>();

            // list에 3개의 문자열을 저장합니다.
            list.add("kim");
            list.add("lee");
            list.add("kim");

            System.out.println(list.size()); //list에 저장된 자료의 수를 출력 (중복을 허용하므로 3 출력) 
            for(int i = 0; i < list.size(); i++){
                String str = list.get(i);
                System.out.println(str);
            }
        }   
    }

Map

Map은 key와 value를 쌍으로 저장하는 자료구조이다. 키는 중복될 수 없고, 값은 중복될 수 있다.

    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;   
    public class MapExam {  
        public static void main(String[] args) {
            // Key, Value가 모두 String 타입인 HashMap인스턴스를 만듭니다.
            Map<String, String> map = new HashMap<>();

            // key와 value값을 put으로 저장합니다.
            map.put("001", "kim");
            map.put("002", "lee");
            map.put("003", "choi");
            // 같은 key가 2개 있을 수 없습니다. 첫번째로 저장했던 001, kim은 001, kang으로 바뀐다.
            map.put("001", "kang");

            // map에 저장된 자료의 수를 추력합니다. 3이 출력됩니다.
            System.out.println(map.size());

            // 키가 001, 002, 003인 값을 꺼내 출력합니다.
            System.out.println(map.get("001"));
            System.out.println(map.get("002"));
            System.out.println(map.get("003"));

            // map에 저장된 모든 key들을 Set자료구조로 꺼냅니다.
            Set<String> keys = map.keySet();
            // Set자료구조에 있는 모든 key를 꺼내기 위하여 Iterator를 구합니다.
            Iterator<String> iter = keys.iterator();
            while (iter.hasNext()) {
                // key를 꺼냅니다.
                String key = iter.next();
                // key에 해당하는 value를 꺼냅니다.
                String value = map.get(key);
                // key와 value를 출력합니다.
                System.out.println(key + " : " + value);
            }
        }
    }

쌍(pair)으로 자료를 관리하는 Map 인터페이스를 구현한 클래스와 그 활용

HashMap 클래스

가장 많이 사용되는 Map 인터페이스 기반 클래스

key - value를 쌍으로 관리하는 메서드를 구현함

검색을 위한 자료구조

key를 이용하여 값을 저정하고 key를 이용하여 값을 꺼내오는 방식 - hash 알고리즘으로 구현 됨

key가 되는 객체는 중복될 수 없고 객체의 유일성을 비교를 위한 equals()와 hashCode() 메서드를 구현해야 함

TreeMap 클래스

Map 인터페이스를 구현한 클래스이고 key에 대한 정렬을 구현할 수 있음

key가 되는 클래스에 Comparable이나 Comparator인터페이스를 구현함으로써 key-value 쌍의 자료를 key값 기준으로 정렬하여 관리 할 수 있음

Collection 요소를 순회하는 Iterator

요소의 순회란?

컬렉션 프레임워크에 저장된 요소들을 하나씩 차례로 참조하는것

순서가 있는 List인터페이스의 경우는 Iterator를 사용 하지 않고 get(i) 메서드를 활용할 수 있음

Set 인터페이스의 경우 get(i) 메서드가 제공되지 않으므로 Iterator를 활용하여 객체를 순회함

Iterator 사용하기

boolean hasNext() : 이후에 요소가 더 있는지를 체크하는 메서드, 요소가 있다면 true를 반환

E next() : 다음에 있는 요소를 반환

Date

날짜와 시간을 구하기 위한 클래스 Date 클래스

  • Date클래스는 JDK 1.0때 만들어졌고, Calendar클래스는 JDK1.1에 만들어졌다.
  • Date는 지역화에 대한 부분이 고려되지 않았다.
    지역화란, 지역에 따라서 시간, 통화(원, 달러, 엔 등) 언어등에 대하여 고려하는 프로그래밍을 지역화에 맞춘 프로그래밍이다.
  • Date클래스를 보면 대부분의 생성자와 메소드가 Deprecated되어 있다.
    Deprecated된 것은 앞으로 지원을 안하거나 문제가 있을 수 있으니 사용하지 말라는 뜻이다.
  • 기본 생성자를 이용한 Date클래스 생성
    기본 생성자로 Date인스턴스를 만들게 되면 현재 시간과 날짜 정보를 Date인스턴스가 가지게 된다.
    Date date = new Date();
  • toString()메소드를 이용하여 현재 시간을 문자열로 구한다.
    출력 결과 : Wed Jan 06 18:36:56 KST 2016
    System.out.println(date.toString());
  • java.util.SimpleDateFormat 클래스를 이용해서 원하는 형태로 출력하는 방법
    yyyy는 년, MM은 월, dd는 일을 표현한다.
    hh는 시간, mm은 분, ss는 초를 표현하며 a는 오전/오후 를 표현한다.
    zzz는 TimeZone을 나타낸다. 한국의 경우 한국표준시 KST가 TimeZone에 해당하는 값이다.
    SimpleDateFormat ft =  new SimpleDateFormat ("yyyy.MM.dd 'at' hh:mm:ss a zzz");     
    System.out.println(ft.format(date));  
  • 현재 시간을 Long값으로 구하는 방법
    System.out.println(date.getTime());
    // System이 가지고 있는 currentTimeMillis()메소드를 이용해도 됩니다.
    long today = System.currentTimeMillis();
    System.out.println(today);

Calendar

Date의 단점을 해결하고 등장한 것이 Calendar클래스

Calendar 클래스 생생 방법

  • Calendar클래스는 추상클래스이다.
  • Calendar클래스에 대한 인스턴스를 생성하려면 Calendar가 가지고 있는 클래스 메소드 getInstance()를 사용해야 한다.
  • getInstance()메소드를 호출하면 내부적으로 java.util.GregorianCalendar 인스턴스를 만들어서 리턴한다.
  • GregorianCalendar는 Calendar의 자식 클래스이다.
    Calendar cal = Calendar.getInstance();

Calendar 클래스를 이용해서 현재 날짜와 시간에 대한 정보를 알아내는 방법

  • Calendar는 현재 날짜와 시간에 대한 정보를 가진다.
  • Calendar가 가지고 있는 get메소드에 Calendar의 상수를 어떤 것을 넣어주느냐에 따라서 다른 값이 나오게 된다.
        int yyyy = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1; // 월은 0부터 시작합니다.
        int date = cal.get(Calendar.DATE);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);

Calendar 클래스를 이용해서 원하는 날짜나 시간에 대한 정보 얻어오는 방법

  • Calendar가 가지고 있는 add메소드를 이용하면 쉽게 다음 날짜나 이전 날짜를 구할 수 있다.
  • 현재 캘린더에 시간을 5시간 더하는 방법. 5를 -5로 수정하면 5시가 전을 구할 수 있게 된다.
        cal.add(Calendar.HOUR, 5);

java.time 패키지

Java에서 제공하는 Date, Time API는 부족한 기능 지원을 포함한 여러가지 문제점을 가지고 있었다. JDK 코어에서 이런 문제점들을 해결하고 더 좋고 직관적인 API들을 제공하기 위해 새롭게 재 디자인한 Date, Time API를 Java SE 8부터 제공한다.

  • 새로운 API의 핵심 클래스는 오브젝트를 생성하기 위해 다양한 factory 메소드를 사용한다.

  • 오브젝트 자기 자신의 특정 요소를 가지고 오브젝트를 생성할 경우 of 메소드를 호출하면 되고, 다른 타입으로 변경할 경우에는 from 메소드를 호출하면 된다.

  • LocalDateTime 클래스를 이용해서 현재 시간 time객체 만드는 방법
    now는 현재 시간을 구한다.

        LocalDateTime timePoint = LocalDateTime.now(); // 현재의 날짜와 시간
  • 원하는 시간으로 time객체 생성하는 방법
    // 2012년 12월 12일의 시간에 대한 정보를 가지는 LocalDate객체를 만드는 방법  
    LocalDate ld1 = LocalDate.of(2012, Month.DECEMBER, 12); // 2012-12-12 from values

        // 17시 18분에 대한 LocalTime객체를 구한다.
    LocalTime lt1 = LocalTime.of(17, 18); // 17:18 (17시 18분)the train I took home today

    // 10시 15분 30초라는 문자열에 대한 LocalTime객체를 구한다.
    LocalTime lt2 = LocalTime.parse("10:15:30"); // From a String
  • 현재와 날짜와 시간정보를 getter메소드를 이용하여 구하는 방법
    LocalDate theDate = timePoint.toLocalDate();
    Month month = timePoint.getMonth();
    int day = timePoint.getDayOfMonth();
    int hour = timePoint.getHour();
    int minute = timePoint.getMinute();
    int second = timePoint.getSecond();
    // 달을 숫자로 출력한다 1월도 1부터 시작하는 것을 알 수 있습니다. 
    System.out.println(month.getValue() + "/" + day + "  " + hour + ":" + minute + ":" + second);

자바IO

입출력을 위한 인터페이스와 클래스들




자바 IO는 크게 byte단위 입출력과 문자 단위 입출력 클래스로 나뉜다.

  • byte단위 입출력클래스는 모두 InputStream과 OutputStream이라는 추상클래스를 상속받아 만들어진다.
  • 문자(char)단위 입출력클래스는 모두 Reader와 Writer라는 추상클래스를 상속받아 만들어집니다.

4가지 추상클래스(InputStream,OutputStream,Reader,Writer)를 받아들이는 생성자가 있다면, 다양한 입출력방법을 제공하는 클래스이다.

4가지 클래스를 받아들이는 생성자가 없다면, 어디로부터 입력받을 것인지, 어디에 쓸것인지를 나타내는 클래스이다.

파일로부터 입력받고 쓰기 위한 클래스 : FileInputStream, FileOutputStream, FileReader, FileWriter
배열로부터 입력받고 쓰기 위한 클래스 : ByteArrayInputStream, ByteArrayOutputStream, CharReader, CharWriter

  • 해당 클래스들은 어디로부터, 어디에라는 대상을 지정할 수 있는 IO클래스이다. 이런 클래스를 장식대상 클래스라고 한다.

DataInputStream, DataOutputStream같은 클래스를 보면 다양한 데이터 형을 입력받고 출력한다.
PrintWriter는 다양하게 한줄 출력하는 println()메소드를 가지고 있다.
BufferedReader는 한줄 입력받는 readLine()메소드를 가진다.

  • 이런 클래스들은 다양한 방식으로 입력하고, 출력하는 기능을 제공한다. 이런 클래스를 장식하는 클래스라고 한다.

Byte 단위 입출력

Byte단위 입출력 클래스는 클래스의 이름이 InputStream이나 OutputStream으로 끝난다.

파일로부터 1byte씩 읽어들여 파일에 1byte씩 저장하는 프로그램을 작성

  • 파일로부터 읽어오기 위한 객체 - FileInputStream
  • 파일에 쓸 수 있게 해주는 객체 - FileOutputStream

read()메소드가 byte를 리턴한다면 끝을 나타내는 값을 표현할 수가 없기 때문에, byte가 아닌 int를 리턴한다.

  • 음수의 경우 맨 좌측 비트가 1이 된다. 읽어들일 것이 있다면 항상 양수를 리턴한다고 볼 수 있다.

FileInputStream과 FileOutputStream을 이용하여, 1바이트씩 읽어들여 1바이트씩 저장

  • read()메소드가 리턴하는 타입은 정수인데, 정수 4바이트중 마지막 바이트에 읽어들인 1바이트를 저장한다.
  • read()메소드는 더이상 읽어들일 것이 없을때 -1을 리턴한다.

    public class ByteIOExam1 {
        public static void main(String[] args){     
            FileInputStream fis = null; 
            FileOutputStream fos = null;        
            try {
                fis = new FileInputStream("src/javaIO/exam/ByteExam1.java");
                fos = new FileOutputStream("byte.txt");

                int readData = -1; 
                while((readData = fis.read())!= -1){
                    fos.write(readData);
                }           
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                try {
                    fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

Byte 단위 입출력 심화

Byte단위 입출력 클래스는 클래스의 이름이 InputStream이나 OutputStream으로 끝난다.

파일로부터 512byte씩 읽어들여 파일에 512byte씩 저장하는 프로그램을 작성

  • byte[] buffer = new byte[512];
  • 512byte만큼 읽어 들이기 위해 byte배열을 사용
    public class ByteIOExam1 {
        public static void main(String[] args){     
            //메소드가 시작된 시간을 구하기 위함
            long startTime = System.currentTimeMillis();        
            FileInputStream fis = null; 
            FileOutputStream fos = null;        
            try {
                fis = new FileInputStream("src/javaIO/exam/ByteExam1.java");
                fos = new FileOutputStream("byte.txt");

                int readCount = -1; 
                byte[] buffer = new byte[512];
                while((readCount = fis.read(buffer))!= -1){
                    fos.write(buffer,0,readCount);
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                try {
                    fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        //메소드가 끝났을때 시간을 구하기 위함. 
        long endTime = System.currentTimeMillis();
        //메소드를 수행하는데 걸린 시간을 구할 수 있음. 
        System.out.println(endTime-startTime); 
        }
    }

System.currentTimeMillis();

  • 현재 시간을 롱타입으로 반환한다.

다양한 타입의 출력

try-with-resources 블럭 선언

  • java io객체는 인스턴스를 만들고, 모두 사용하면 close()메소드를 호출해야 한다.
  • close()메소드를 사용자가 호출하지 않더라도, Exception이 발생하지 않았다면 자동으로 close()가 되게 할 수 있는 방법
        try(
                //io객체 선언
        ){
                //io객체 사용
        }catch(Exception ex){
            ex.printStackTrace();
        }

다양한 타입으로 저장 할 수 있는 DataOutputStream

  • writeInt() - 정수값으로 저장
  • writeBoolean() - boolean값으로 저장
  • writeDouble() - double 값으로 저장
    import java.io.DataOutputStream;
    import java.io.FileOutputStream;    
    public class ByteExam3 {    
        public static void main(String[] args) {
            try(
                    DataOutputStream out = new DataOutputStream(new FileOutputStream("data.txt"));
            ){
                out.writeInt(100);
                out.writeBoolean(true);
                out.writeDouble(50.5);
            }catch (Exception e) {
                e.printStackTrace();
            }
        }   
    }

다양한 타입의 입력

data.txt로부터 값을 읽어들여 화면에 출력하는 클래스

다양한 타입의 데이터를 읽어낼 수 있는 DataInputStream

  • readInt() - 정수를 읽어들이는 메소드
  • readBoolean() - boolean 값을 읽어들이는 메소드
  • readDouble() - double 값을 읽어들이는 메소드
    import java.io.DataInputStream;
    import java.io.FileInputStream;

    public class ByteIOExam4 {

        public static void main(String[] args) {
            try(
                    DataInputStream out = new DataInputStream(new FileInputStream("data.dat"));
            ){
                int i = out.readInt();          
                boolean b = out.readBoolean();          
                double d = out.readDouble();

                System.out.println(i);
                System.out.println(b);
                System.out.println(d);
            }catch(Exception ex){
                ex.printStackTrace();
            }
        }
    }

파일에 저장된 순서대로 읽어 들여야한다.
int, boolean, double순서대로 저장하였기 때문에 읽어들일 때도 같은 순서로 읽어여야 한다.

Char 단위 입출력(Console)

char단위 입출력 클래스는 클래스 이름이 Reader나 Writer로 끝이 난다.

char단위 입출력 클래스를 이용해서 키보드로부터 한줄 입력 받아서 콘솔에 출력

  • System.in - 키보드를 의미 (InputStream)
  • BufferedReader - 한줄씩 입력받기 위한 클래스
  • BufferedReader 클래스의 생성자는 InputStream을 입력받는 생성자가 없다.
  • System.in은 InputStream 타입이므로 BufferedReader의 생성자에 바로 들어갈 수 없으므로 InputStreamReader 클래스를 이용해야함.

    import java.io.BufferedReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter; 
    public class CharIOExam01 {
        public static void main(String[] args) {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            //키보드로 입력받은 문자열을 저장하기 위해 line변수를 선언               
            String line = null;     
            try {
                line = br.readLine()
            } catch (IOException e) {
                e.printStackTrace();
            }
            //콘솔에 출력 
            System.out.println(line);
        }
    }

Char 단위 입출력(File)

char단위 입출력 클래스는 클래스 이름이 Reader나 Writer로 끝이 난다.

파일에서 한 줄씩 입력 받아서 파일에 출력

  • 파일에서 읽기 위해서 FileReader 클래스 이용
  • 한 줄 읽어 들이기 위해서 BufferedReader 클래스 이용
  • BufferedReader 클래스가 가지고 있는 readLine() 메소드가 한줄씩 읽게 해준다.
  • readLine() 메소드는 읽어낼 때 더 이상 읽어 들일 내용이 없을 때 null을 리턴한다.
  • 파일에 쓰게 하기 위해서 FileWriter 클래스 이용
  • 편리하게 출력하기 위해서 PrintWriter 클래스 이용
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter; 
    public class CharIOExam02 {
        public static void main(String[] args) {
            BufferedReader br = null; 
            PrintWriter pw = null;
            try{        
                br = new BufferedReader(new FileReader("src/javaIO/exam/CharIOExam02.java"));
                pw = new PrintWriter(new FileWriter("test.txt"));
                String line = null;
                while((line = br.readLine())!= null){
                    pw.println(line);
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally {
                pw.close();
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
profile
귀여운 설이에양

0개의 댓글