데이터를 ListMap에 넣어 사용하면서 필요한 내용만 골라서 사용해야 하는 경우 Loop를 돌리는 방법도 있지만 stream을 이용하면 쉽게 필터링이 가능 합니다.

 

stream을 이용하기 때문에 리턴값이 stream으로 넘어오지만 collect를 사용하여 필요한 형태로 가공하여 받아올 수도 있습니다.

 

 

 

 

먼저 List에 있는 데이터를 필터링 하는 방법입니다.

 

        List<String> list = new ArrayList<>();
        list.add("test");
        list.add("atest");
        list.add("test1");
        list.add("btest");
        list.add("ctest");
        list.add("test2");
        list.add("dtest");
        list.add("etest");
       
        Stream<String> filter = list.stream().filter(l->l.startsWith("t"));
        filter.forEach(System.out::println);
 
        List<String> lst = list.stream().filter(l->l.startsWith("t"))
                       .collect(Collectors.toList());
        System.out.println("List : " + lst);

 

첫번째 system.outstream으로 받아온 예제이고

두번째는 collect를 이용하여 다시 List로 받아오는 내용입니다.

 

첫번째 결과는

test
test1
test2

 

두번째는

 

List : [test, test1, test2]

 

 

다음은 Map<String, String>을 필터링 하는 방법입니다.

 

Map<String, String> map = new HashMap<>();
              
map.put("aa", "ba");
map.put("baa", "abb");
map.put("abb", "bbb");
map.put("caa", "acc");
map.put("aac", "aac");
map.put("aad", "cad");
              
Map<String, String> filterMap = map.entrySet()
        .stream().filter(f->f.getKey().startsWith("a"))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println("key : " + filterMap);
              
Map<String, String> filterVal = map.entrySet()
        .stream().filter(f->f.getValue().startsWith("a"))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println("value : " + filterVal);
              
Map<String, String> conMap = map.entrySet()
        .stream().filter(f->f.getKey().contains("a"))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println("contain : " + conMap);

 

첫번째는 key 값이 “a”로 시작하는 내용만 필터링하고

두번째는 value 값이 “a”로 시작하는 내용만 필터링하고

세번째는 key 값에 “a”가 들어있는 내용만 필터링하는 예제 입니다.

 

각각의 결과는

 

key : {aa=ba, abb=bbb, aac=aac, aad=cad}
value : {caa=acc, aac=aac, baa=abb}
contain : {aa=ba, abb=bbb, caa=acc, aac=aac, baa=abb, aad=cad}

 

 

이번에는 Map<Integer, String>을 필터링 하는 방법입니다.

 

Map<Integer, String> intMap = new HashMap<>();
              
intMap.put(10, "ba");
intMap.put(20, "abb");
intMap.put(30, "bbb");
intMap.put(40, "acc");
intMap.put(50, "aac");
intMap.put(60, "cad");
              
Map<Integer, String> intFilter = intMap.entrySet()
        .stream().filter(x->x.getKey() > 30)
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println("intMap : " + intFilter);
              
              
Map<Integer, String> intMap2 = new HashMap<>();
for(Map.Entry<Integer, String> intmap : intMap.entrySet()) {
        if(intmap.getKey() > 30)
               intMap2.put(intmap.getKey(), intmap.getValue());
}
System.out.println("intMap : " + intMap2);

 

key 값이 숫자인 경우 조건식으로 필터링 하는 방법입니다.

결과는 동일한데 추출하는 방법을 하나는 for문을 사용해 봤습니다.

 

intMap : {50=aac, 40=acc, 60=cad}
intMap : {50=aac, 40=acc, 60=cad}

 - copy coding -

 

폴더에 있는 파일을 읽어와서 보여주는 간단한 프로그램 입니다.

웹에서 파일을 다운로드 해줘야 하는데 Batch로 파일이 계속 생성되고 있어서 목록을 수작업으로 하려니 귀찮아서 자동으로 파일 목록을 생성하도록 하기위한 기초적인 부분입니다.

 

Windows에서는 C:\\folderName으로 하면 되고 UNIX/LINUX/usr/copycoding 이런식으로 폴더명을 변경하면 됩니다.

 

현재 D:\\temp라는 folder에는 파일과 하부 폴더가 아래 그림과 같이 존재 합니다.

 

 

폴더와 파일을 불러오는 프로그램 소스는 매우 간단 합니다.

 

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
 
public class DirList {
 
        public static void main(String[] args) {
               // TODO Auto-generated method stub
                 String dirName = "D:\\temp";
              File dir = new File(dirName);
      
              File[] files2 = dir.listFiles();
              for(File f: files2){
                    String str = f.getName();
              
                    if(f.isDirectory()){
                        System.out.print(str+"\t");
                        System.out.print("DIR\n");
                    }else{
                        long ltime = f.lastModified();
                        String pattern = "yyyy-MM-dd hh:mm aa";
                               SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
                              
                               Date lastModifiedDate = new Date( ltime );
                               String frmDate = simpleDateFormat.format(lastModifiedDate);
                              
                        System.out.print(str+"/\t"+ frmDate + "/\t" +  f.length()+"bytes\n");
                      
                    }
                  
                }
 
        }
 
}

 

폴더이면 폴더명만 출력하고 파일이면 파일명과 작성일자 그리고 사이즈를 출력 합니다.

이걸 실행하면 아래와 같은 결과가 출력 됩니다.

 

backup_0808.txt/      2022-05-16 04:59 오후/ 242bytes
backup_0809.txt/      2022-05-16 04:59 오후/ 242bytes
backup_0810.txt/      2022-05-16 04:59 오후/ 242bytes
backup_0811.txt/      2022-05-16 04:59 오후/ 242bytes
backup_배치.bat/       2022-05-16 04:59 오후/ 242bytes
연습1   DIR
연습2   DIR

 

 

연습1, 연습2는 폴더인데 이것의 내부에 있는 파일명도 필요하다면 파일 목록 출력하는 부분을 method로 만들어서 호출하면 될것 같고.

Vo하나 만들어서 List<Vo>에 담아 화면에 던지면 끝이네요.

 

 

댓글에 너무 설명이 부족해서 몇자 추가합니다.

 

외부에서 호출할 URI와 Method를 생성 합니다.

@GetMapping("/fine_info")
public String fileInfo(Model model) {

}

Vo는 File과 관련된 어떤 내용을 보여줄지에 따라서 생성합니다.

class FileInfo {
      private String fileName;
      private String fileTime;

       getter/setter 추가...

}

그리고 method내에서

List<FileInfo>를 선언하고 FileInfo의 setter에 값을 하나씩 추가해 주고 화면으로 값을 넘겨 줍니다.

 

 

개발자에 따라 다양한 이름으로 불리기도 하는데 사용법이 간단해서 if문을 사용하기 번거로운 경우에 자주 사용하곤 합니다.  

그러다 보니 많은 언어에서 사용 되고 있는데 조건이 복잡해지면 그냥 if문을 사용하는게 좋을 때도 있는데 if문을 사용할 수 없는 상황에서는 직관적이지 않은 경우도 발생 합니다.

 

 

기본적인 삼항 연산자 표현은 다음과 같습니다.

조건식 ? 반환값1 : 반환값2

조건식이 참이면 반환값1을 조건식이 거짓이면 반환값2를 넘겨주는 단순한 연산자 입니다.

 

예제를 하나 만들어 보는게 제일 이해하기 쉽죠.

var nAA = 1;
var nBB = 2;
 
var nZZ = (nAA > nBB) ? 10 : 20;
 
console.log(nZZ);
console.log((nAA > nBB) ? 10 : 20);
결과 20

 

그러나 조금 더 복잡하게 삼항 연산자가 중복되게 작업을 해야 하는 경우도 있습니다. 

var nAA = 1;
var nBB = 2;
var nCC = 3;
 
var nFF = (nAA != nBB) ? nCC < 5 ? 6 : 7 : 4;
 
console.log(nFF);
console.log((nAA != nBB) ? nCC < 5 ? 6 : 7 : 4);
결과 : 6

예제는 간단하게 표시했지만 실제 사용할때는 조건과 반환값이 길어져서 눈동자를 왔다갔다 하게 만드는데 이런 경우에는 보기가 쉽지 않으니 괄호를 이용해 조금 단순하게 표시해 주면 이해하기 편합니다.

 

var nFF = (nAA != nBB) ? (nCC < 5 ? 6 : 7) : 4;

 

이렇게 하면 첫번째 예문과 동일한 구조이고 내부에 하나가 추가된것을 확인할 수 있습니다.

추가된 조건문이 복잡해지는 경우에도

var nAA = 1;
var nBB = 2;
var nCC = 3;
 
var nFF = (nAA != nBB) ? nCC < 5 && nBB == 3 ? 6 : 7 : 4;
 
console.log(nFF);
console.log((nAA != nBB) ? nCC < 5 && nBB == 3 ? 6 : 7 : 4);
결과 : 7

 

var nFF = (nAA != nBB) ? ((nCC < 5 && nBB == 3) ? 6 : 7) : 4;

 

이렇게 괄호를 이용하면 좀더 쉽게 구조를 파악할 수 있습니다.

 

만일 조건이 좀더 많아진다면 

var nAA = 1;
var nBB = 2;
var nCC = 3;
var nDD = 4;
var nEE = 5;
 
var nGG = nAA == nBB ? 11 : nAA == nCC ? 22 : nAA == nDD ? 33 : 44;
 
console.log(nGG);
console.log(nAA == nBB ? 11 : nAA == nCC ? 22 : nAA == nDD ? 33 : 44);
결과 : 44

 

이런 경우는 if 조건문 처럼 줄바꿈을 해주면 보기가 편해집니다. 

var nAA = 1;
var nBB = 2;
var nCC = 3;
var nDD = 4;
var nEE = 5;
 
var nGG = nAA == nBB ? 11
        : nAA == nCC ? 22
        : nAA == nDD ? 33
        : 44;
 
console.log(nGG);
console.log(nAA == nBB ? 11
        : nAA == nCC ? 22
        : nAA == nDD ? 33
        : 44);
결과 : 44

 

이렇게 하고 보면

if(nAA == nBB) return 11

else if(nAA == nCC) return 22

좀더 친숙한 if ~ else 문과 비슷하게 인식하고 사용할 수 있습니다.

 

nexacro 작업하다 grid 표현식 때문에 사용할 때마다 기억이 가물거려 정리를 해봅니다.

숫자 대신 text, edit, combo등을 사용하면 되겠죠?

 

- copy coding -

 

html tag를 데이터베이스에 저장하기위해 특수문자를 변환해야 하는 경우가 발생합니다.  DB에 저장을 했으니 웹 페이지에 뿌릴때는 반대의 작업을 해야 하는데 이때 Spring을 사용한다면 특별히 라이브러리를 설치하지 않고도 변환이 가능합니다.

 

간단한 예제를 살펴 보면

import org.springframework.web.util.HtmlUtils;
 
        String tag ="<HTML> <table><tr><div> &";
        String esc = HtmlUtils.htmlEscape(tag);
        String uesc = HtmlUtils.htmlUnescape(esc);
 
        System.out.println("escape : " + esc);
        System.out.println("uescape : " + uesc);

 

이렇게 "<HTML> <table><tr><div> &” HTML 문서가 있는 경우 htmlEscape htmlUnescape 함수를 이용하면

 

escape : &lt;HTML&gt; &lt;table&gt;&lt;tr&gt;&lt;div&gt; &amp;
uescape : <HTML> <table><tr><div> &

 

이렇게 쉽게 변환이 가능 합니다.

 

만약 일반적인 특수 기호나 숫자, 알파벳을 변환하려고 하면 어떻게 될까요?

 

        String sTag = "( ) \\ [ ] { } ! @ $ % ^ * 1 2 3 A B C";
        String sEsc = HtmlUtils.htmlEscape(sTag);
        String sUesc = HtmlUtils.htmlUnescape(sEsc);
       
        System.out.println("escape : " + sEsc);
        System.out.println("uescape : " + sUesc);

 

escape : ( ) \ [ ] { } ! @ $ % ^ * 1 2 3 A B C
uescape : ( ) \ [ ] { } ! @ $ % ^ * 1 2 3 A B C

 

아쉽게도 아무런 변화가 없습니다.

 

 

그럼 escape 문자를 변환하면

 

String nTag = "&#40; &#41; &#92; &#91; &#93; &#123; &#125; &#49; &#50; &#65; &#66; ";
String nUesc = HtmlUtils.htmlUnescape(nTag);
              
System.out.println("escape : " + nUesc);

 

uescape : ( ) \ [ ] { } 1 2 A B

 

잘 변환이 됩니다.

 

그런데 굳이 일반 문자나 숫자를 변환할 일은 많지 않을것 같군요.

 

- copy coding -


12345···7

+ Recent posts