- 드디어 자바(JAVA) 공부에서 정식 교육의 끝이 보인다..
그동안 자바(JAVA)를 사용하다보면 객체 지향 프로그래밍에서 메소드를 선언하기 위해
반드시 클래스를 정의해야 되고 다른 언어에 비해 써야 하는 식의 절차도 너무 많고
따져야 하는 게 너무 많아서 복잡해보임을 느끼는 경우가 많다
그래서 자바(JAVA)가 도입한 것이 람다식이다.
- 메소드를 간단한 식으로 표현하여 함수형 프로그래밍에 적합한 문법
- 객체화보다 기능 하나가 필요한 상황에서 주로 사용한다.
- 입력 받은 자료를 기반으로 수행되고 외부에 영향을 미치지 않으므로 병렬처리등에 가능
안정적인 확장성 있는 프로그래밍 방식- 클래스를 생성하지 않고 함수의 호출만으로 기능을 수행
(매개변수목록) -> { 함수몸체 }
매개변수가 하나인 경우 자료형과 소괄호를 생략할 수 있다.
중괄호 안의 구현부가 한 문장인 경우 중괄호를 생략할 수 있다.
메소드 몸체가 둘 이상의 문장으로 이뤄져있거나, 매개변수의 수가 둘 이상인 경우에는
ㄴ각각 중괄호와 소괄호의 생략이 불가능하다
중괄호 안의 구현부가 한 문장이라도 return 문이 있다면 중괄호를 생략할 수 없다.
메소드 몸체에 해당하는 내용이 return 문이면 그 문장이 하나이더라도 중괄호 생략이 불가능하다.
Unit10 unit = () -> { // 매개변수 없으면 '()' 생략 불가능
중괄호 안의 구현부가 반환문 하나라면 return 과 중괄호 모두 생략할 수 있다.
@FunctionalInterface
함수형 인터페이스라는 의미, 여러 개의 메소드를 선언하면 에러남
@FunctionalInterface
interface Calc { // 함수형 인터페이스의 선언
public int min(int x, int y);
}
public class Lambda02 {
public static void main(String[] args){
Calc minNum = (x, y) -> x < y ? x : y; // 추상 메소드의 구현
System.out.println(minNum.min(3, 4)); // 함수형 인터페이스의 사용
}
}
▣ 미리 정의된 함수형 인터페이스
▣ 문법:
클래스이름::메소드이름
또는
참조변수이름::메소드이름
MyClass obj = new MyClass;
Function<String, Boolean> func = (a) -> obj.equals(a); // 람다 표현식
Function<String, Boolean> func = obj::equals(a); // 메소드 참조
- 입력스트림(Input Stream) : 프로그램으로 부터 데이터를 읽어들이는 스트림
- 출력스트림(Output Stream) : 프로그램으로 부터 데이터를 내보내는 스트림
- 스트림 연산은 기존 자료를 변경하지 않는다.
- 스트림 연산은 중간 연산과 최종 연산으로 구분된다.
- 한 번 생성하고 사용한 스트림은 재사용 할 수 없다.
sort() 중간 연산은 스트림을 구성하는 데이터를 조건에 따라 정렬하는 연산을 한다.
map() 중간 연산은 스트림을 구성하는 데이터를 조건에 따라 변환하는 연산을 한다.
reduce() : 정의된 연산이 아닌 프로그래머가 직접 구현한 연산
최종 연산으로 스트림의 요소를 소모하여 연산을 수행한다
최종 연산이기에 1회만 사용 가능하다
// 합
int sum = IntStream.of(1, 3, 5, 7, 9) // 1회만 사용이 가능하므로 계속 선언
.sum();
System.out.println("sum = " + sum);
// 개수
long cnt = IntStream.of(1, 3, 5, 7, 9)
.count();
System.out.println("count = " + cnt);
// 평균
IntStream.of(1, 3, 5, 7, 9)
.average() // 자동 double 형 변환
.ifPresent(avg -> System.out.println("avg = " + avg));
// ifPresent => 값이 존재하면 실행할 것
// 최소
IntStream.of(1, 3, 5, 7, 9)
.min()
.ifPresent(min -> System.out.println("min = " + min));
// 최대
IntStream.of(1, 3, 5, 7, 9)
.max()
.ifPresent(max -> System.out.println("max = " + max));
※ 파이프라인 구성
Stream 인터페이스가 제공하는 메소드는 대부분 반환 타입이 Stream 이므로
메소드를 연속적으로 호출할 수 있다.
따라서 스트림 연산을 연결해 파이프라인으로 구성할 수 있다.
스트림을 사용하면 컬렉션을 사용한 것보다 코드가 간결하고, 쉽게 의미를 알 수 있다. 배열에서 홀수만 골라내서 정렬하여 출력하는 코드
◈ 바이트스트림
데이터를 있는 그대로 송수신한다.
바이트 스트림을 이용해서 문자를 파일에 저장하는것이 가능하다.
단, 자바가 아닌 Windows, Linux에서 읽을때 문제가 발생한다.
입출력 스트림이 필요한 대부분의 프로그램에서 바이트 스트림을 사용한다.
▶ Fileinputstream -> 한글이 깨진다.
ㄴ1바이트씩 읽기 때문이다. (한글은 2바이트)
- 해결방법- FileReader나 FileWriter 클래스를 사용하면 2바이트씩 읽기에
한글이 깨지지 않는다 (예시: UTF-8)
▶ Buffer : 보조스트림 : 좀 더 편하고 빨라진다.
ㄴBuffered(Input/Output)Stream : 1바이트 기반의 버퍼 입출력 스트림이다.
- BufferedReader나 BufferedWriter는 문자 기반 버퍼 입출력 스트림이며
데이터를 모아서 전송하기에 반드시 ★★★ throw IOException 예외처리가 필수이다.
☆ public String readLine() throws IOException
-> 문자열을 반환, 반환할 문자열이 없으면 null
ㄴBufferedReader 메소드이다.
★ public void write(String s, int off, int len) throws IOException
-> 문자열 s를 인덱스 off부터 len개의 문자까지 저장한다.
ㄴBufferedWriter 메소드이다.
# 직렬화(Serialization)란 객체가 파일의 형태로 저장되는 것을
'직렬화' 라고 한다.
- 직렬화를 하는 이유
우리가 컴퓨터로 작업할 때 zip 파일을 사용하는 것과 비슷하다고 볼 수 있다.
그냥 폴더자체는 이메일에 첨부하거나 온라인에 업로드하는 게 쉽지 않다.
파일이 깨지는 경우도 있다. 하지만 zip 파일을 사용하면 안전하게 파일을 첨부하거나 업로드할 수 있다. 필요할 때 가져다쓰는 것도 쉽다.
- 객체 직렬화 serialization ; 객체의 데이터(필드값)를 연속적인 바이트로 변경하는 작업 -> 작업 후 [쓰기] 가능 = 스트림에 객체를 출력 = ObjectOutputStream 사용
- 객체 역직렬화 deserialization ; 연속적인 바이트를 객체의 데이터(필드값)로 복원하는 것 -> 작업 후 [읽기] 가능 = 스트림으로부터 객체를 입력 = ObjectInputStream 사용
class Circle implements Serializable {
int xPos, yPos;
double radian;
...코드생략
}
직렬화의 대상이 되는 인스턴스의 클래스는 java.io.Seiralizable
인터페이스를 구현해야 한다. ( 필수 상속 )
이 인터페이스는 ‘직렬화의 대상임을 표시’하는 기능을 가진다.
Q. 5명의 연예인(이름, 성별, 키)을 입력받아서 인터페이스에 정의된 test() 추상메서드를 오버라이딩해서
람다식으로 정의 후 남자 연예인, 여자 연예인 평균키를 구하는 프로그램을 만드시오
Q. Supplier로 0~99까지 랜덤 난수를 10개 생성하는 프로그램을 만드시오
Q. Function<T, E>을 적용하여 람다식을 적용한 후 "kama_code fighting!"의 문자열의 길이를 출력하시오
Q. 사용자로부터 영어로 된 단어 3가지를 입력받고
람다식을 사용하여 map과 forEach문을 통해 대문자로 출력하는 프로그램을 만드시오
Q. 사용자로부터 검색어 아이디와 비밀번호를 입력받아 계정 저장 프로그램을 만드시오
1. 추가 2. 검색 3. 삭제 4. 전체보기 5. 종료로 메뉴는 구성한다.
입력된 정보는 TXT 파일에 저장되어 읽고 쓸 수 있어야 한다.
class Entertain
{
String name,gender; int tall;
// 생성자
public Entertain(String name, String gender, int tall)
{
this.name = name;
this.gender = gender;
this.tall = tall;
}
// 성별 getter
public String getGender()
{
return gender;
}
// 키 getter
public int gettall()
{
return tall;
}
}
public class Lamda01
{
public static void main(String[] args)
{
/*
Q. 5명의 연예인(이름, 성별, 키)을 입력받아서 인터페이스에 정의된
test() 추상메서드를 오버라이딩해서 람다식으로 정의 후
남자 연예인, 여자 연예인 평균키를 구하는 프로그램을 만드시오
*/
// 입력값을 받는 scan
Scanner scan = new Scanner(System.in);
// 번째를 안내하기 위한 변수
int count = 1;
Entertain [] et = new Entertain[5]; // et 배열 선언
// 0부터 4까지 = 5번 반복
for(int i=0; i<et.length; i++)
{
System.out.println("["+count+"번쨰] 연예인의 이름을 입력해주세요.");
System.out.print(">>");
String name = scan.nextLine().trim(); // 공백 제거하여 name에 저장
System.out.println("["+count+"번쨰] 연예인의 성별을 입력해주세요.");
System.out.print(">>");
String gender = scan.nextLine().trim(); // 공백 제거하여 gender에 저장
System.out.println("["+count+"번쨰] 연예인의 키(cm)를 숫자만 입력해주세요.");
System.out.print(">>");
String tall = scan.nextLine().trim(); // 공백 제거하여 tall에 저장
// et[i] 배열에 담아서 객체 생성하기
et[i] = new Entertain(name, gender, Integer.parseInt(tall)); // 배열 원소 객체 생성
count++; // 카운트 1씩 증가
}
// list 형식으로 변환
List<Entertain> list = Arrays.asList(et[0], et[1], et[2], et[3],et[4]);
// 람다식을 정의하고 참조변수는 aaa를 전달하는 것
// 리스트 안에서 남자라는 것을 인식하여 평균을 구하기 위한 메소드 avg
double maleAvg = avg((Entertain h) -> h.getGender().equals("남자"), list);
System.out.println("남자 평균:"+ maleAvg);
// 리스트 안에서 여자라는 것을 인식하여 평균을 구하기 위한 메소드 avg
double femaleAvg = avg((Entertain b) -> b.getGender().equals("여자"), list);
System.out.println("여자 평균:"+ femaleAvg);
}
/*
매개변수로 성별을 판단하는 람다식과 list 컬렉션을 전달 받는다
*/
public static double avg(Predicate<Entertain> ph, List<Entertain> li)
{
int pCount = 0;
int tCount = 0;
//컬렉션에 저장된 Entertain 객체의 갯수만큼 5번 반복
for(Entertain h : li)
{
// 람다식을 통해 각 Entertain 객체의 성별을 판단
// test()이 실제 일치하는지 확인
if(ph.test(h)== true)
{
// 각 성별을 판단한 후 + 합니다
pCount++;
tCount += h.gettall();
//키를 누적해가며 더합니다.
}
}
return (double)tCount / pCount; // 키를 인원수만큼 나눈다(평균)
}
}
여기서 핵심은 람다식의 문법에 맞게 함수 인터페이스(Supplier)를 통해
랜덤을 생성해준 후 get()을 통해 값을 얻어오는 것이다.
그리고 10개의 난수를 얻어오기 위해 makeRandomNum 메소드를 생성해준 후
반복문을 통해 출력하는 것이 핵심이다.
public static void main(String[] args) {
//0~99까지 난수를 생성한 후 반환해주는 람다식 정의
Supplier<Integer> sup = () -> {
Random random = new Random();
return random.nextInt(100);
};
//추상메서드인 get()을 호출
int rNum = sup.get();
System.out.println("생성된난수="+ rNum);
//난수를 생성하는 람다식 sup과 정수 10을 인수로 전달
List<Integer> list = makeRandomNum(sup, 10);
Collections.sort(list); // 오름차순 정렬
//리스트 자체를 반복문 없이 출력할 수 있다. toString() 메소드가 이미 오버라이딩 되어 있어서 출력
System.out.println(list);
}
/*
매개변수로 전달된 람다식을 통해 난수를 생성한다. 이때 cnt만큼 반복하게 되므로
결국 난수 10개를 생성하여 list컬렉션에 저장한 후 반환
*/
public static List<Integer> makeRandomNum(Supplier<Integer> s, int cnt)
{
List<Integer> li = new ArrayList<Integer>();
for(int i=1 ; i<=cnt ; i++)
{
/*
람다식의 get()메서드 호출을 통해 난수를 생성하게 된다.
*/
li.add(s.get());
}
return li;
}
}
public static void main(String[] args)
{
/*
Q. Function<T, E>을 적용하여 람다식을 적용한 후
"kama_code fighting!"의 문자열의 길이를 출력하시오
*/
//매개변수는 String, 반환값은 Integer인 람다식을 정의
//문자열의 길이(.length)를 반환
Function<String, Integer> func = (String s) -> {
return s.length(); // 오버라이딩
};
System.out.println("kama_code fighting! 문자열길이="+ func.apply("kama_code fighting!")); // 길이 19개
}
}
해당 프로그램 역시 간단하다. 문제 그대로 사용자로부터 3개의 영단어를
입력 받도록 한다. 그리고 그 내용을 배열에 담는다.
스트림으로 변경하여 map을 통해 toUpperCase()로 대문자로 바꾸는 메소드를 사용한다.
마지막으로 반복문을 통해서 출력하는 문제이다.
람다식으로 사용하니 굉장히 코드가 짧아진다.
public static void main(String[] args)
{
/*
* Q. 사용자로부터 영어로 된 단어 3가지를 입력받고 람다식을 사용하여
* map과 forEach문을 통해 대문자로 출력하는 프로그램을 만드시오
*/
Scanner scan =new Scanner(System.in);
System.out.println("[첫번째] 영어단어를 입력해주세요");
String ineng1 = scan.nextLine();
System.out.println("[두번째] 영어단어를 입력해주세요");
String ineng2 = scan.nextLine();
System.out.println("[세번째] 영어단어를 입력해주세요");
String ineng3 = scan.nextLine();
List<String> list = Arrays.asList(ineng1, ineng2, ineng3); // 변경이 안되는 배열
list.stream() // 스트림으로 변환
.map(s -> s.toUpperCase()) // 대문자로 변환
// map은 data 원형을 변경하는데 사용
.forEach(n -> System.out.print(n + "\t"));
System.out.println(); // 한줄 띄기
}
public static void main(String[] args) throws IOException
{
ArrayList<Idfinder> idf = new ArrayList<Idfinder>();
//Idfinder의 데이터를 가지는 ArrayList의 변수를 idf이라고 만들고
//Idfinder의 데이터를 가지는 ArrayList의 객체를 만들어서 변수 idf에 대입
Controller c = new Controller();
//Controller 라는 클래스 변수 이름을 c로 하고 Controller 객체를 생성해서 대입
File f = new File("src/text.txt");
if(f.exists()) // 파일 존재여부를 확인하는 메소드
{
// idf.clear();
//ArrayList idf의 내용 클리어해서 idf을 비움
FileReader fr = new FileReader("src/text.txt");
//FileReader fr에 FileReader 객체를 생성 생성자 인자에는 파일경로를 문저열로 넣어서 객체 생성
BufferedReader reader1 = new BufferedReader(fr);
// BufferReader reader1에 BufferedReader 객체를 생성 생성자 인자에는 FileReader을 넣어서 객체 생성
String line1;
//문자열 line1 생성
String[] splitLine1 = null;
//문자열 배열 splitLine을 생성 하고 null 값 대입
while((line1=reader1.readLine()) != null)
//BufferReader reader1을 이용해 한줄을 읽어 와서 문자열 line1에 대입하고 line1이 널이 아니면 반복
{
//System.out.println(line1);
splitLine1 = line1.split("\t\t");
//문자열 splitLine 배열에 line1을 "\t\t"로 자른 문자열들을 대입
// System.out.println(splitLine.length);
idf.add(new Idfinder(splitLine1[0], splitLine1[1], splitLine1[2]));
//ArrayList idf 추가할때 Idfinder 객체를 생성 하고 생성자는 문자열 splitLine1 배열을 대입
}
}
while(true) //무한반복
{
try
{
Scanner sc = new Scanner(System.in); //입력
FileWriter fw; //FileWriter의 fw라는 변수 선언
System.out.println("========== 아이디 보관 프로그램 ==========");
System.out.println("1.추가 2.검색 3.삭제 4.전체보기 5.종료"); //출력
int num = sc.nextInt(); // 입력
if(c.idf.size() < 0)
//Controller의 변수 c의 객체변서 idf의 사이즈가 0이면 실행
{
fw = new FileWriter("src/text.txt",false);
// fw 변수에 FileWriter 객체를 생성해서 대입
// 객체 생성시 파일 경로명 문자열 생성자 인자에 넣어서 객체 생성 대입
//덮어쓰기
}
else //if문이 아니면
{
//System.out.println("11");
fw = new FileWriter("src/text.txt",true);
//fw 변수에 FileWriter 객체를 생성해서 대입
// 객체 생성시 파일 경로명 문자열 생성자 인자에 넣어서 객체 생성 대입
//이어쓰기
}
switch (num)
{ //num의 값에 따라 분기
case 1: //num 1이면
c.input(fw);
// Controller의 변수 c의 input 함수에 FileWriter 객체 fw를 인자로 넣어서 호출
break; //탈출
case 2: //num 2이면
c.search();
//Controller의 변수 c의 search 함수 호출
break; // 탈출
case 3: //num 3이면
FileWriter fw1 = new FileWriter("src/text.txt",false);
//FileWriter의 변수명 fw1로 선언 후 FileWriter 객체 생성
//객체 생성시 파일 경로명을 문자열로 인자로 전달해서 객체 생성
c.delete(fw1);
//Controller의 변수 c의 deleter 함수에 FileWriter 객체 fw1를 인자로 넣어서 호출
break;//탈출
case 4://num 3이면
System.out.println("[검색어] [아이디] [비밀번호]");
c.allPrint();
//Controller의 변수 c의 allPrint 함수 호출
break;// 탈출
case 5:
System.out.println("========== 프로그램을 종료합니다 ==========");//입력
return;//탈출
default: //위에게 다아니면
System.out.println("잘못된 입력입니다.");
System.out.println("1~5번까지의 숫자만 입력해주세요.");//출력
break;//탈출
}
}
catch (InputMismatchException num)
{
System.out.println("잘못된 입력입니다.");
System.out.println("1~5번까지의 숫자만 입력해주세요.");//출력
}
}
}
}
class Idfinder //클래스 Idfinder
{
String name; // 문자열 변수 name
String idNum; // 문자열 변수 idNum
String password; // 문자열 변수 password
public Idfinder(String name, String idNum, String password) {
//Idfinder 생성자 인자로 문자열 name, 문자열 idNum, 문자열 password 받아서 생성
this.name = name;
//인자 name을 객체 변수 name에 대입
this.idNum = idNum;
//인자 idNum을 객체 변수 idNum에 대입
this.password = password;
//인자 password을 객체 변수 password에 대입
}
}
class Controller //class Controller
{
ArrayList<Idfinder> idf; // Idfinder이 있는 ArrayList를 idf이라고 선언
FileWriter fw; // FileWriter를 fw라고 선언
Scanner sc; // Scanner를 sc라고 선언
FileReader fr; // FileReader를 fr이라고 선언
public Controller() throws IOException
{
idf = new ArrayList<Idfinder>();
// idf 변수에 ArrayList<Idfinder>객체 생성 해서 대입
sc = new Scanner(System.in); // 입력
}
void input(FileWriter fw) throws IOException
//인자를 FileWriter로 받고 리턴이 없는 input이라는 함수
{
if(idf.size() < 0) // ArrayList 변수 idf의 크기가 0이면 실행
{
String opn1 = "검색어"+"\t\t"+"아이디(ID)"+"\t\t"+"비밀번호(PW)"+"\r\n";
//문자열 변수 opn1에 위에 문자열 대입
idf.add(new Idfinder("검색어","아이디(ID)","비밀번호(PW)"));
//ArrayList 변수 idf의 리스트 추가 Idfinder 객체를 생성해서 추가
fw.write(opn1);
// FileWrite의 변수 fw를 이용해 write 함수 호출 파일에 문자열 쓰기
}
System.out.print("검색어 :"); //입력
String name = sc.next(); // String name에 입력 값 대입
System.out.print("아이디(ID) :"); //입력
String number=sc.next(); // String number에 입력 값 대입
System.out.print("비밀번호(PW) :"); // 입력
String password = sc.next(); // String password에 입력 값 대입
idf.add(new Idfinder(name,number,password));
//ArrayList 변수 idf의 리스트 추가 Idfinder 객체를 생성해서 추가 Idfinder은 입력받은 값을 생성자에 추가
String tatal = name+"\t\t"+number+"\t\t"+password+"\r\n";
// 문자열 tatal 에 입력 받은 문자열을 더해서 대입
fw.write(tatal);
// FileWrite의 변수 fw를 이용해 write 함수 호출 파일에 tatal문자열 쓰기
System.out.println("============ 아이디 등록완료 ============");
System.out.println("["+name+"] 성공적으로 추가되었습니다");
System.out.println("아이디(ID) : ["+number+"]");
System.out.println("비밀번호(PW) : ["+password+"]");
System.out.println();
fw.close();
//FileWriter 끄기
}
void search() throws IOException
//인자가 없고 리턴이 없는 search 함수
{
System.out.print("검색어를 입력해주세요 : "); //입력
String search = sc.next(); // 문자열 search에 입력 문자열 대입
idf.clear();
//ArrayList idf의 내용 클리어해서 idf을 비움
FileReader fr = new FileReader("src/text.txt");
//FileReader fr에 FileReader 객체를 생성 생성자 인자에는 파일경로를 문저열로 넣어서 객체 생성
BufferedReader reader1 = new BufferedReader(fr);
// BufferReader reader1에 BufferedReader 객체를 생성 생성자 인자에는 FileReader을 넣어서 객체 생성
String line1;
//문자열 line1 생성
String[] splitLine1 = null;
//문자열 배열 splitLine을 생성 하고 null 값 대입
while((line1=reader1.readLine()) != null)
//BufferReader reader1을 이용해 한줄을 읽어 와서 문자열 line1에 대입하고 line1이 널이 아니면 반복
{
//System.out.println(line1);
splitLine1 = line1.split("\t\t");
//문자열 splitLine 배열에 line1을 "\t\t"로 자른 문자열들을 대입
// System.out.println(splitLine.length);
idf.add(new Idfinder(splitLine1[0], splitLine1[1], splitLine1[2]));
//ArrayList idf 추가할때 Idfinder 객체를 생성 하고 생성자는 문자열 splitLine1 배열을 대입
}
boolean check = false; // boolean check 변수를 false로 초기화
int index = -1; // int index 변수를 -1로 초기화
for(int i = 0;i<idf.size();i++)
//int i 변수를 0으로 대입 i는 ArrayList idf의 크기보다 작으면 반복 반복 때마다 i는 1씩 증가
{
if(idf.get(i).name.equals(search))
//ArrayList idf에 i 인덱스에 이름이 search와 같으면 아래 명령어 실행
{
index = i; // 변수 index에 i를 대입
check = true; // 변수 check에 true 대입
}
}
if(check == true)
// 변수 check가 true 라면 아래 명령어 실행
{
System.out.println("========== 성공적으로 찾았습니다 ==========");
System.out.println("[검색어] [아이디] [비밀번호]");
System.out.println(idf.get(index).name +" "+ idf.get(index).idNum+" "+idf.get(index).password );//출력
}
else
{
System.out.println("▶▷ 등록된 아이디(ID)가 없습니다.");//출력
System.out.println();
}
}
void delete(FileWriter fw) throws IOException
//인자를 FileWriter를 받고 리턴값이 없는 delete라는 함수
{
System.out.print("삭제 할 검색어를 입력해주세요 : ");// 출력
String search1 = sc.next();
//문자열 search1 에 입력 값 대입
for(int i = 0;i<idf.size();i++)
//int i 변수를 0으로 대입 i는 ArrayList idf의 크기보다 작으면 반복 반복 때마다 i는 1씩 증가
{
if(idf.get(i).name.equals(search1))
//ArrayList idf에 i 인덱스에 이름이 search와 같으면 아래 명령어 실행
{
System.out.println("▶▷ 성공적으로 삭제되었습니다.");//출력
System.out.println();
idf.remove(i);//ArrayList idf 에 i 인덱스 삭제
}
}
for(int i =0;i<idf.size();i++)
//int i 변수를 0으로 대입 i는 ArrayList idf의 크기보다 작으면 반복 반복 때마다 i는 1씩 증가
{
String tatal1 = idf.get(i).name+"\t\t"+idf.get(i).idNum+"\t\t"+idf.get(i).password+"\r\n";
//문자열 tatal1에 ArrayList idf에 i인덱스 문자열 이름, 전화번호, 주소를 더해서 대입
fw.write(tatal1);
// FileWrite의 변수 fw를 이용해 write 함수 호출 파일에 tatal1문자열 쓰기
}
fw.close();
//FileWriter 끄기
}
void allPrint() throws IOException
//인자는 없고 리턴값도 없는 allPrint라는 함수
{
idf.clear();
//ArrayList idf의 내용 클리어해서 idf을 비움
FileReader fr = new FileReader("src/text.txt");
//FileReader fr에 FileReader 객체를 생성 생성자 인자에는 파일경로를 문저열로 넣어서 객체 생성
BufferedReader reader1 = new BufferedReader(fr);
// BufferReader reader1에 BufferedReader 객체를 생성 생성자 인자에는 FileReader을 넣어서 객체 생성
String line1;
//문자열 line1 생성
String[] splitLine1 = null;
//문자열 배열 splitLine을 생성 하고 null 값 대입
while((line1=reader1.readLine()) != null)
//BufferReader reader1을 이용해 한줄을 읽어 와서 문자열 line1에 대입하고 line1이 널이 아니면 반복
{
//System.out.println(line1);
splitLine1 = line1.split("\t\t");
//문자열 splitLine 배열에 line1을 "\t\t"로 자른 문자열들을 대입
// System.out.println(splitLine.length);
idf.add(new Idfinder(splitLine1[0], splitLine1[1], splitLine1[2]));
//ArrayList idf 추가할때 Idfinder 객체를 생성 하고 생성자는 문자열 splitLine1 배열을 대입
}
for(int i = 0;i<idf.size();i++)
//int i 변수를 0으로 대입 i는 ArrayList idf의 크기보다 작으면 반복 반복 때마다 i는 1씩 증가
{
System.out.println(idf.get(i).name + "\t\t"+idf.get(i).idNum +"\t\t"+ idf.get(i).password);
//출력
}
}
}
이렇게 람다식과 스트림까지도 끝이 났다.
자바(Java)공부 초기 때는 숫자와 문자 하나만 넣고 다루고 그랬는데
후반부로 오니까 클래스를 넣고 파일을 넣고 다루게 된다.
원리는 초기때와 같다는 것! 자바(java)는 기본이 중요하다는 것을 명심하다!
기본에서 파생되어 심화되고 응용되는 것이다.
tip] 스트림을 다루다가 가끔 한글이 깨지고 그러는 경우가 있는데
이클립스에서 실행하지 말고 notepad++에서 넣으면 정상적으로 한글이 안깨질때도 있다
그렇게 불러와서 전체 선택하여 가지고 오는 것도 팁이다.
그리고 위 문제에서 클래스를 하나로 쭉 써넣었는데
왠만하면 클래스는 파일 안에서 나누는 것이 좋다.
class1.java // class2.java 이런식으로 말이다. 그래야 코딩하는데
가독성도 좋아지고 객체 지향처럼 나뉘게 되니까 구분하기도 편리하다.