본문 바로가기
Programming Language/Java

[국비] Java 내용정리 Day20

by tpleehan 2021. 12. 4.

Regular Expression Quiz01

- 형식이 맞지 않은 문자열에서 숫자의 가격 형식만 찾아서 순서대로 출력한다.
package regex.pattern;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexQuiz {

	public static void main(String[] args) {

		String str = "헠4,500원 힣~ 1,200원엌? 6000원윀 120000원";

		String pattern = "\\d원*";
		
		Pattern p = Pattern.compile(pattern);
		Matcher m = p.matcher(str);
		
		while(m.find()) {
			System.out.printf(m.group());
		}
		
		/*
		String pattern = "\\d+,*[0-9]+원";
		
		Matcher m = Pattern.compile(pattern).matcher(str);
		
		while(m.find()) {
			System.out.println(m.group());
		}
		 */
	}

}​

Regular Expression Quiz02

- 상품번호, 업소명(도시락명), 가격으로 분리해서 출력한다.
- 정규표현식에서 (): 괄호 안에 들어 있는 문자를 하나의 문자열로 인식하고, \\( : 특수문자 (가 존재하는지 확인한다.
package regex.pattern;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexQuiz02 {

	public static void main(String[] args) {

		String str1 = "123123-4564564 GU24(치킨도시락) 4,400원";
		String str2 = "111111-2222222 CM(마늘햄도시락) 5,500원";
		String str3 = "333333-4444444 MAXSHOP(제육도시락) 5,000원";
		
		String pattern1 = "\\d{6}-\\d{7}";
		String pattern2 = "[A-Z]+[0-9]*";
		String pattern3 = "\\([가-힣]+\\)";
		String pattern4 = "[0-9],[0-9]+원";
		
		String[] arr = {str1, str2, str3};
		
		/* 
		for (String str : arr) {
			Matcher m1 = Pattern.compile(pattern1).matcher(str);
			Matcher m2 = Pattern.compile(pattern2).matcher(str);
			Matcher m3 = Pattern.compile(pattern3).matcher(str);
			Matcher m4 = Pattern.compile(pattern4).matcher(str);
			
			if (m1.find() && m2.find() && m3.find() && m4.find()) {
				System.out.println("----------------------");
				System.out.println("제품번호: " + m1.group());
				System.out.println("업소명: " + m2.group());
				System.out.println("도시락명: " + m3.group());
				System.out.println("가격: " + m4.group());
			}
			
		}
		 */

		int i = 0;
		
		while(i < arr.length) {
			System.out.println("-------------------------");
			Matcher m1 = Pattern.compile(pattern1).matcher(arr[i]);
			Matcher m2 = Pattern.compile(pattern2).matcher(arr[i]);
			Matcher m3 = Pattern.compile(pattern3).matcher(arr[i]);
			Matcher m4 = Pattern.compile(pattern4).matcher(arr[i]);
			
			if (m1.find() && m2.find() && m3.find() && m4.find()) {
				System.out.println("제품번호: " + m1.group());
				System.out.println("업소명: " + m2.group());
				System.out.println("도시락명: " + m3.group());
				System.out.println("가격: " + m4.group());
			}
			
			i++;
		}
	}

}​

Regular Expression Quiz03

1. day, store, grade, detail, price를 멤버로 갖는 Product 클래스를 선언
2. 은닉을 이용해서 클래스를 디자인
3. MainClass에 Product 타입을 갖는 ArrayList를 생성
4. BufferedReader를 통해서 건담.txt파일을 읽어들인다. (인코딩 방식 -> UTF-8)
5. while문 안에서는 readLine()메서드를 이용해서 한 줄씩 읽도록 처리
6. 날짜, 지점, 등급, 상세, 가격 패턴 분석을 통해서 Product에 저장후 리스트에 추가
    상세 같은 경우에는 정규 표현식 패턴으로 구분하기 어려울 수 있기 때문에 등급패턴의 끝지점 ~ 가격패턴의
    시작지점 미만까지 부분추출 하시는 것을 추천 (substring(begin, end))
    추출 완료 후 객체를 리스트에 담기가 완료된 후 각 객체의 상세 내용을 출력
    (Product의 toString을 이용해서 간단하게 출력)
7. 외부 라이브러리를 사용해서 분석한 패턴을 xlsx 엑셀 파일로 추출
    엑셀파일객체 생성 후에 FileOutputStream을 사용하여 파일을 작성 (확장자는 xlsx)
package regex.pattern;

public class Product {

	private String day;
	private String store;
	private String grade;
	private String detail;
	private String price;

	public Product() {
	}
	
	public Product(String day, String store, String grade, String detail, String price) {
		super();
		this.day = day;
		this.store = store;
		this.grade = grade;
		this.detail = detail;
		this.price = price;
	}
	
	public String getDay() {
		return day;
	}
	public void setDay(String day) {
		this.day = day;
	}
	public String getStore() {
		return store;
	}
	public void setStore(String store) {
		this.store = store;
	}
	public String getGrade() {
		return grade;
	}
	public void setGrade(String grade) {
		this.grade = grade;
	}
	public String getDetail() {
		return detail;
	}
	public void setDetail(String detail) {
		this.detail = detail;
	}
	public String getPrice() {
		return price;
	}
	public void setPrice(String price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "날짜: " + day + ", 지점: " + store + ", 등급: " + grade + ", 상품명: " + detail + ", 가격: "
				+ price;
	}
	
}​
package regex.pattern;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class RegexQuiz03 {

	public static void main(String[] args) {

		List<Product> list = new ArrayList<>();

		BufferedReader br = null;
		
//		FileInputStream fis = null;
//		InputStreamReader is = null;
		
		try {
//			fis = new FileInputStream("C:\\java\\건담.txt");
//			is = new InputStreamReader(fis, "UTF-8");
			br = new BufferedReader(new InputStreamReader(new FileInputStream("C:\\java\\건담.txt"), "UTF-8"));
			
			String line;
			while((line = br.readLine()) != null) {
				
				// 정규표현식
				String pattern1 = "\\d{8}-\\d{2}-\\d{12,13}"; // 날짜 패턴
				String pattern2 = "[가-힣]+ [가-힣]+"; // 가게 패턴
				String pattern3 = "\\[[A-Z가-힣]*\\]"; // 등급 패턴
				String pattern4 = "\\d+,*\\d+원"; // 가격 패턴
				
				Matcher m1 = Pattern.compile(pattern1).matcher(line);
				Matcher m2 = Pattern.compile(pattern2).matcher(line);
				Matcher m3 = Pattern.compile(pattern3).matcher(line);
				Matcher m4 = Pattern.compile(pattern4).matcher(line);
				
							
				if (m1.find() && m2.find() && m3.find() && m4.find()) {
					
					String day = m1.group();
					String store = m2.group();
					String grade = m3.group();
					// 등급패턴의 끝지점  + 1 ~ 가격패턴의 시작지점 - 1
					String detail = line.substring(m3.end()+1, m4.start()-1);
					String price = m4.group();
					
					Product p = new Product(day, store, grade, detail, price);
					list.add(p);

				}
				
			}
			/*
			list.stream().forEach((data) -> {
				System.out.println("----------------------------------");
				System.out.println(data);
			});
			 */
			
			// 엑셀 메서드를 호출해서 엑셀 파일 생성
			excel(list);
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	// 엑셀 출력 메서드
	public static void excel(List<Product> list) {
		
		// 워크북 생성
		XSSFWorkbook wb = new XSSFWorkbook();
		
		// 워크시트 생성
		XSSFSheet sheet = wb.createSheet("건담");
		
		// 행 생성
		XSSFRow row = sheet.createRow(0);
		
		// 셀 생성
		XSSFCell cell;
		
		// 헤더 정보 구성
		cell = row.createCell(0);
		cell.setCellValue("날짜");
		
		cell = row.createCell(1);
		cell.setCellValue("지점");

		cell = row.createCell(2);
		cell.setCellValue("등급");
		
		cell = row.createCell(3);
		cell.setCellValue("상세");
		
		cell = row.createCell(4);
		cell.setCellValue("가격");
		
		// 리스트의 size만큼 row를 생성
		Product vo;
		
		for(int i = 0; i < list.size(); i++) {
			vo = list.get(i);
			
			// 행 생성
			row = sheet.createRow(i + 1);
			
			cell = row.createCell(0);
			cell.setCellValue(vo.getDay());
			
			cell = row.createCell(1);
			cell.setCellValue(vo.getStore());
			
			cell = row.createCell(2);
			cell.setCellValue(vo.getGrade());
			
			cell = row.createCell(3);
			cell.setCellValue(vo.getDetail());
			
			cell = row.createCell(4);
			cell.setCellValue(vo.getPrice());
		}
		
		// 파일 쓰기
		FileOutputStream fos = null;
		
		try {
			fos = new FileOutputStream("C:\\java\\건담.xlsx");
			wb.write(fos);
			System.out.println("엑셀 파일 생성 성공");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("엑셀 파일 생성 실패");
		} finally {
			try {
				wb.close();
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

}​

멀티 스레드

  • 스레드는 프로그램의 실행흐름 이다.
  • 프로그램 내에 스레드가 2개라면 두 개의 코드 흐름이 생기다는 뜻이다.

스레드 사용방법

방법1

  1. Runnable 인터페이스를 상속받아 run() 추상메서드를 재정의 한다.
  2. Thread 객체의 생성자의 매개 값으로 전달한다.
  3. start() 메서드르 통해 실행시킨다.

방법2

  1. Thread 클래스를 상속받아 run() 추상메서드를 재정의 한다.
  2. Thread 객체의 생성자의 매개 값으로 전달한다.
  3. start() 메서드르 통해 실행시킨다.

두 개의 차이

  • Runnable은 인터페이스로 스레드 실행의 기능만 정의되어 있기 때문에 클래스 내부에서 사용할 수 있는 메서드가 한정적이다. (스레드의 static 메서드는 전부 사용이 가능하다.)
  • Thread 클래스의 기능을 전부 받아서 사용할 수 있다.

스레드 기본 메서드

  • start()
    • 스레드 클래스를 실행한다.
  • currentThread() (static)
    • 현재 스레드를 반환한다.
  • getName()
    • 스레드 이름을 반환한다.
  • sleep() (static)
    • 스레드를 잠시 멈춘다.
  • yield()
    • 스레드 실행을 다른 스레드에게 양보한다.
  • join()
    • 해당 스레드를 우선 실행한다.
package thread.ex01;

public class ThreadTest implements Runnable {

	int num = 0;
	
	@Override
	public void run() {
		
		System.out.println("쓰레드 시작");
		
		for (int i = 1; i <= 10; i++) {			
			if (Thread.currentThread().getName().equals("쓰레드1")) {
				System.out.println("-------------------");
				num++;
			}
			System.out.println("현재 쓰레드: " + Thread.currentThread().getName());
			System.out.println("num: " + num);
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
}
package thread.ex01;

public class MainClass {

	public static void main(String[] args) {		
		// 객체 2개, 쓰레드 2개 (2개의 쓰레드가 각각 실행)		
		ThreadTest t1 = new ThreadTest();
		ThreadTest t2 = new ThreadTest();
		
		Thread thread1 = new Thread(t1, "쓰레드1");
		Thread thread2 = new Thread(t2, "쓰레드2");
		
		thread1.start();
		thread2.start();
		
		System.out.println("메인 쓰레드 종료");
	}

}
package thread.ex01;

public class MainClass02 {

	public static void main(String[] args) {		
		// 객체 1개, 쓰레드 n개 (1개의 객체를 실행)		
		ThreadTest t1 = new ThreadTest();
		
		Thread thread1 = new Thread(t1, "쓰레드1");
		Thread thread2 = new Thread(t1, "쓰레드2");
		
		thread1.start();
		thread2.start();
		
		System.out.println("메인 쓰레드 종료");
	}

}
package thread.ex02;

public class ThreadTest extends Thread {

	@Override
	public void run() {
		System.out.println(getName());
		System.out.println("쓰레드 시작");
		
		for (int i = 1; i <= 10; i++) {
			System.out.println(i);
			
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
}
package thread.ex02;

public class MainClass {

	public static void main(String[] args) {		
		ThreadTest t1 = new ThreadTest();
		t1.setName("쓰레드1");
		t1.start();		
	}

}
package thread.ex03_syncro;

public class ThreadTest implements Runnable {

	int num = 0;
	
	@Override
	public synchronized void run() {		
		System.out.println("쓰레드 시작");
		
		for (int i = 1; i <= 10; i++) {
			
			if (Thread.currentThread().getName().equals("쓰레드1")) {
				System.out.println("-------------------");
				num++;
			}
			System.out.println("현재 쓰레드: " + Thread.currentThread().getName());
			System.out.println("num: " + num);
			
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}
package thread.ex03_syncro;

public class MainClass {

	public static void main(String[] args) {
		
		ThreadTest t1 = new ThreadTest();
		
		Thread thread1 = new Thread(t1, "쓰레드1");
		Thread thread2 = new Thread(t1, "쓰레드2");
		
		thread1.start();
		thread2.start();
		
		System.out.println("메인 쓰레드 종료");
	}

}
package thread.ex04_yield;

public class TestA implements Runnable {

	public boolean work = true;
	
	@Override
	public void run() {			
		while (true) {
			if (work) {
				System.out.println("A쓰레드 실행 중");
			} else {
				Thread.yield(); // 실행 양보
			}
			
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}		
	}
	
}
package thread.ex04_yield;

public class TestB implements Runnable {

	@Override
	public void run() {			
		while (true) {
			System.out.println("B쓰레드 실행 중");
			
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}		
	}
	
}
package thread.ex04_yield;

public class MainClass {

	public static void main(String[] args) {
		
		TestA a = new TestA();
		TestB b = new TestB();
		
		Thread t1 = new Thread(a);
		Thread t2 = new Thread(b);
		
		t1.start();
		t2.start();

		try {
			Thread.sleep(3000);
			a.work = false;
			
			Thread.sleep(3000);
			a.work = true;
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}

}
  • Thread.yield()는 쓰레드를 일시 정지 상태로 만들거나 정지된 쓰레드를 다시 실행시키게 할 수 있다
  • 실행 중인 쓰레드의 상태를 변경하는 것을 쓰레드 상태 제어라고 하며, 그 중 yield는 일시 정지를 구현할 수 있다.
package thread.ex05_join;

public class TestA implements Runnable {

	private int sum;
	
	@Override
	public void run() {		
		for (int i = 1; i <= 100; i++) {
			sum += i;
			System.out.println("A의 누적합: " + sum);
		}
		
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}		
	}
	
	public int getSum() {
		return sum;
	}
	
}
package thread.ex05_join;

public class MainClass {

	public static void main(String[] args) {

		TestA a = new TestA();
		Thread t = new Thread(a);
		
		t.start();
		
		try {			
			t.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("계산 결과: " + a.getSum());		
	}

}
  • join() 메서드는 해당 쓰레드가 종료 될 때 까지 다른 쓰레드를 정지 시킨다.
  • 다른 쓰레드가 종료 될 때 까지 기다리다가 실행해야 하는 경우 사용한다.
    ex) B라는 쓰레드가 계산을 마치고 그 결과값으로 A쓰레드가 로직을 처리할 때 등등

Lambda Stream Quiz

- run() 메서드 안에는 랜덤값을 이용해서 개표 진행사항을 화면에 출력한다.
- 멤버변수: int finish -> 최대 개표율
                   int sum -> 개표율
                   Random r -> 난수 생성용
                   StringBuilder -> *찍기용

조건: 개표율은 100%가 최대값.
문자는 StringBuilder를 이용하여 개표율만큼의 *을 출력
개표율은 1 ~ 10까지의 난수를 생성해서 개표율에 적용
개표가 한 번 일어날 때마다 스레드는 1초씩 일시정지
package thread.quiz;

import java.util.Random;

public class VoteThread implements Runnable {

	final int finish = 100; // 개표 끝
	int sum = 0; // 개표율
	Random r = new Random();
	StringBuilder sb = new StringBuilder();
	
	@Override
	public void run() {
		
		while (true) {
			int num = r.nextInt(10) + 1;
			sum += num;
			
			if (finish > sum) { // 개표가 덜 된 경우
				for (int i = 1; i <= num; i++) {
					sb.append("*");					
				}
				System.out.println(Thread.currentThread().getName() + "개표율: " + sum + "%: " + sb + "\n");
			} else { // 개표율이 100보다 큰 경우
				sum = 100;
				sb.delete(0, sum);
				for (int i = 1; i <= 100; i++) {
					sb.append("*");
				}
				System.out.println(Thread.currentThread().getName() + "개표율: " + sum + "%: " + sb);
				break;
			}
			
			try {
				Thread.sleep(300);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		} // end while(true)
		
		System.out.println("\n" + Thread.currentThread().getName() + "의 개표가 완료되었습니다." + "\n");
		
	}

}​

 

package thread.quiz;

public class MainClass {

	public static void main(String[] args) {		
		VoteThread voteLocation1 = new VoteThread();
		VoteThread voteLocation2 = new VoteThread();
		VoteThread voteLocation3 = new VoteThread();
		
		Thread location1 = new Thread(voteLocation1, "Location1");
		Thread location2 = new Thread(voteLocation2, "Location2");
		Thread location3 = new Thread(voteLocation3, "Location3");
		
		location1.start();
		location2.start();
		location3.start();	
	}

}

'Programming Language > Java' 카테고리의 다른 글

[국비] Java 내용정리 Day19  (0) 2021.12.02
[국비] Java 내용정리 Day18  (0) 2021.12.01
[국비] Java 내용정리 Day17  (0) 2021.11.29
[국비] Java 내용정리 Day16  (0) 2021.11.28
[국비] Java 내용정리 Day15  (0) 2021.11.25

댓글