# chapter 4. 스트림 소개

 

-. 스트림이란

데이터 컬렉션 반복을 멋지게 처리하는 기능.

cf> 스트림을 이용하면 멀티스레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리할 수 있다.

 

[JAVA 7]

List<Dish> lowColoricDishes = new ArrayList<>();

           

for(Dish dish : menu) {

    if(dish.getCalory() < 400) {

        lowColoricDishes.add(dish);

    }

}

           

Collections.sort(lowColoricDishes, new Comparator<Dish>() {

    public int compare(Dish dish1, Dish dish2) {

        return Integer.compare(dish1.getCalory(),  dish2.getCalory());

    }

});

           

List<String> lowCaloricDishesName = new ArrayList<>();

for(Dish dish : lowColoricDishes) {

    lowCaloricDishesName.add(dish.getName());

}

[JAVA 8]

import static java.util.Comparator.comparing;

import static java.uti;l.stream.Collectors.toList;

 

List<String> lowCaloricDishesName = menu.stream()

                                        .filter(d -> d.getCalory() < 400)              // 400칼로리 이하의 요리  선택

                                        .sorted(comparing(Dish::getCalory))            // 칼로리로 요리  정렬

                                        .map(Dish::getName)                            // 요리명  추출

                                        .collect(toList());                            // 모든  요리명을 리스트에 저장

 

filter 같은 연산은 고수준 빌딩 블록으로 이루어져 있으므로 특정 스레딩 모델에 제한되지 않고 자유롭게 어떤 상황에서든 사용할 수 있다.

결과적으로 우리는 데이터 처리 과정을 병렬화하면서 스레드와 락을 걱정할 필요가 없다. 이 모든 것이 스트림 API 덕분이다.

 

자바 8의 스트림 API 특징

  • 선언형 : 더 간결하고 가동성이 좋아진다.

  • 조립할 수 있음 : 유연성이 좋아진다.

  • 병렬화 : 성능이 좋아진다.

-. 스트림 이란

데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소

 

  • 연속된 요소

            컬렉션과 마찬가지로 스트림은 특정 요소 형식으로 이루어진 연속된 값 집합의 인터페이스를 제공한다.

            but, 컬렉션의 주제는 데이터이고 스트림의 주제는 계산이다.

  • 소스

            스트림은 컬렉션, 배열, I/O 자원등의 데이터 제공 소스로부터 데이터를 소비한다.

            즉, 정렬된 컬렉션으로 스트림을 생성하면 정렬이 그대로 유지된다. 

  • 데이터 처리 연산

            스트림은 함수형 프로그래밍 언어에서 일반적으로 지원하는 연산과 데이터베이스와 비슷한 연산을 지원한다.

            ex> filter, map, reduce, find, match

            스트림 연산은 순차적으로 또는 병렬로 실행할 수 있다.

스트림의 중요한 2가지 특징

  • 파이프라이닝

            대부분의 스트림연산은 스트림 연산끼리 연결해서 커다란 파이프 라인을 구성할 수 있도록 스트림 자신을 반환한다.

            연산 파이프라인은 데이터 소스에서 적용하는 데이터베이트 질의와 비슷하다.

  • 내부 반복

            반복자를 이용해서 명시적으로 반복하는 컬렉션과 달리 스트림은 내부 반복을 지원한다.

스트림도 딱 한번만 탐색할 수 있다.

한번 탐색한 요소를 탐색하고 싶다면?) 초기 데이터 소스에서 새로운 스트림을 만들어야 한다.

 

컬렉션과 스트림의 또 다른 차이는 데이터 반복 처리 방법이다.

  • 내부반복 : 스트림

  • 외부반복 : 컬렉션

 

-. 중간연산

스트림을 반환하며 서로 연결할 수 있는 연산

[sample] filter, map, limit 중간연산에 해당

List<String> names = menu.stream()

                                              .filter(dish -> dish.getCalories() > 300)

                                              .map(Dish::getName)

                                              .limit(3)

                                              .collect(toList());

[debug]

List<String> names = menu.stream()

                         .filter(dish -> {

                                    System.out.println("filtering:" + dish.getName());

                                    dish.getCalories() > 300

                                 })

                         .map(dish ->

                                    System.out.println("mapping:" + dish.getName());

                                    return dish.getName();

                                 })

                         .limit(3)

                         .collect(toList());

System.out.println(names);

 

[output]

filtering:pork

mapping:pork

filtering:beef

mapping:beef

filtering:chicken

mapping:chicken

[pork, beef, chicken]

 

=> 하나의 데이터가 중간 연산(filter -> map)과정을 다 돌고나서 다음 데이터를 처리한다.

 

[참고] 중간연산

연산

형식

반환형식

연산의 인수

함수 디스크립터

filter

중간연산

Stream<T>

Predicate<T>

T -> boolean

map

중간연산

Stream<R>

Function<T, R>

T -> R

limit

중간연산

Stream<T>

 

 

sorted

중간연산

Stream<T>

Comparator<T>

(T, T) -> int

distinct

중간연산

Stream<T>

 

 

[참고] 최종연산

연산

형식

반환 형식

목적

forEach

최종연산

void

스트림의 각 요소를 소비하면서 람다를 적용한다.

count

최종연산

long

스트림의 요소 개수를 반환한다

collect

최종연산

 

스트림을 리듀스해서 리스트, 맵, 정수 형식의 컬렉션을 만든다. 

 

 

 

 

 

 

 

 

 

 

# SUBSTR (대상문자열, 시작위치, 길이)

 -> 대상문자열을 시작위치 부터 길이만큼 짜르기 

 

ex>

SUBSTR('방그리하트', 1, 3) 방그리

 

# INSTR(대상문자열, 타겟문자열, 시작위치, 횟수)

 -> 타겟문자열이 시작위치에서 몇 번째에 있는지 위치 반환

 

ex> STR = '방그리는 오늘도 눈부시다'

INSTR(STR, ' ') 5
INSTR(STR, ' ', 7) 9
INSTR(STR, ' ', 7, 1) 9
INSTR(STR, ' ', 7, 2) 0

ps. 시작위치는 1부터 시작한다.

 

 

# 혼합형 예제

SUBSTR(STR, 0, INSTR(STR, ' ', 1, 2)) '방그리는 오늘도 '

 

'cs > db' 카테고리의 다른 글

[oracle]ORA-00918 : 열의 정의가 애매합니다.  (0) 2020.10.07
[oracle] 날짜 계산  (0) 2019.02.25

# ERROR : ORA-00918 : 열의 정의가 애매합니다.

 

# 원인 : 조회시에 같은 이름의 Column이 있고, 조회(select)시에 어떤 값을 사용할 지 결정할 수 없어 나는 오류.

 

# 해결방법

1) ALIAS를 사용하여 이름을 구분지어 중복되는 컬럼 값이 없게 한다.

 

2) 중복되는 컬럼 제거

 

'cs > db' 카테고리의 다른 글

[oracle] SUBSTR, INSTR 문자열 짜르기  (3) 2020.10.13
[oracle] 날짜 계산  (0) 2019.02.25

* 접근 방안

 player를 key값으로, 완주 여부를 value값으로 셋팅하여 완주 여부를 판단 하고자 했습니다.

 

* 문제 해결

 player를 set 할때 1-loop,

 완주 여부를 set할때 1-loop,

 완주 못한 사람은 뽑아낼때 1-loop

 총 3번의 loop를 서칭하게 된다. 이 부분을 어떻게 하면 줄일 수 있을지 고민하였습니다.

 

 고민 끝에

 keySet()를 사용해서 key값을 가져온후(1-loop) value값을 가져오려면(1-loop) 2번의 loop를 돌게 됩니다.  

 이 부분을 entrySet()로 줄일수 있었습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    public static String solution(String[] participant, String[] completion) {
        String answer = "";
        HashMap<String, Integer> hm = new HashMap<>();
        
        for(String player : participant) hm.put(player, hm.getOrDefault(player, 0+ 1);
        for(String finish : completion) hm.put(finish, hm.get(finish) - 1);
        
        for(Map.Entry<String, Integer> map : hm.entrySet()) {
            if(map.getValue() != 0) {
                answer = map.getKey();
            }
        }
        
        return answer;
    }
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

'Algorithm > solution' 카테고리의 다른 글

[프로그래머스 #level3] 네트워크.java  (0) 2021.03.16
[프로그래머스 #level2] 조이스틱.java  (0) 2021.02.23
#2178. 미로탐색  (0) 2018.12.24
#14503. 로봇 청소기  (1) 2018.01.22
#14891. 톱니바퀴  (0) 2018.01.17

* 두 날짜간의 차이를 구하는 함수

1
2
3
4
5
6
7
8
9
10
11
    public static long diffOfDate(String begin, String end) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        
        Date stDt = format.parse(begin);
        Date edDt = format.parse(end);
        
        long diff = edDt.getTime() - stDt.getTime();
        long diffDays = diff / (24 * 60 * 60 * 1000);
        
        return diffDays;
    }
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

* 메인 함수 예제

1
2
3
4
    public static void main(String[] argv) throws Exception {
        long ret = diffOfDate("20191023""20191104");
        System.out.println("ret : " + ret);
    }
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

vue js를 하면서 자바 스크립트 함수도 써보니 정말 좋은거 같다.ㅎㅎ

javascript는 기존의 경험했던 c/c++ 보다 문자열조작에 있어서 상대적으로 쉬운것 같다.

 

- 문자열.split ('element') : element에 따라서 배열을 만들어 준다. 

ex> 'hello my name is eun.'

    => [ "h", "e", "l", "l", "o", " ", "m", "y", " ", "n", "a", "m", "e", " ", "i", "s", " ", "e", "u", "n", "." ]

 

- 배열.reverse() : 배열의 순서를 바꿔준다.

ex> [ "h", "e", "l", "l", "o", " ", "m", "y", " ", "n", "a", "m", "e", " ", "i", "s", " ", "e", "u", "n", "." ]

     => [ ".", "n", "u", "e", " ", "s", "i", " ", "e", "m", "a", "n", " ", "y", "m", " ", "o", "l", "l", "e", "h" ]

 

- 문자열.join('element' : char형 배열을 문자열(string)형으로 만들어준다. element값이 배열 중간중간에 들어간다.

ex1>  .join('')

    [ ".", "n", "u", "e", " ", "s", "i", " ", "e", "m", "a", "n", " ", "y", "m", " ", "o", "l", "l", "e", "h" ]

    => .nue si eman ym olleh

ex2> .join('|')

    [ ".", "n", "u", "e", " ", "s", "i", " ", "e", "m", "a", "n", " ", "y", "m", " ", "o", "l", "l", "e", "h" ]

    => .|n|u|e| |s|i| |e|m|a|n| |y|m| |o|l|l|e|h

'언어 > javascript' 카테고리의 다른 글

[버튼 toggle 처리]  (0) 2019.04.08

// 포맷 설정
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date currentTime = new Date();
String date = format.format(currentTime);

String end_dt = "2019-05-31 00:00:00.0";

Date endDate = format.parse(end_dt);
Date todate = format.parse(date);

System.out.println("endDate:" + endDate);
System.out.println("todate:" + todate);
int compare = endDate.compareTo(todate);

System.out.println("compare:"+ compare);

if(compare >= 0) {
System.out.println("사용가능");
} else {
System.out.println("유효기간만료");
}

'언어 > java' 카테고리의 다른 글

[모던자바 인액션]#4 스트림 소개  (0) 2021.01.13
[JAVA] String으로 입력된 날짜의 차이 구하기  (0) 2019.10.25
자료구조 정리  (0) 2018.12.08
Scanner 정리  (0) 2018.11.29
jar / war 정리  (0) 2018.07.08

디렉티브

  • If / else if / else

=========== Script ===========

Var app = new Vue({

el : ‘#app’, // element finder 잡기

data : {

value : 0 // json형태의 데이터

}

});

=========== HTML ===========

<div id="app">

  <h1 v-if="value > 5"> value 5보다 크군요. </h1>

  <h1 v-else-if="value === 5">값이 5 입니다.</h1>

  <h1 v-else> value 5보다 작습니다. </h1>

<h2 v-once>초기 : {{ value }}</h2>

  <h2>현재 : {{ value }}</h2>

<h1 v-pre>{{ 이건 그대로 렌더링해줘요 }}</h1>

</div>

===========================

 

  • v-bind : 엘리먼트의 속성을 동적으로 사용하자.

? 언제 사용하는가) HTML엘리먼트의 속성값을 데이터값으로 사용하고 싶을때

? 사용법)

=========== Script ===========

// 새로운 뷰를 정의합니다

var app = new Vue({

  el: '#app', // 어떤 엘리먼트에 적용을 정합니다

  // data 해당 뷰에서 사용할 정보를 지닙니다

  data: {

    name: 'Vue',

    mark : true,

    gs : 'https://t1.daumcdn.net/cfile/tistory/1523C2044B42D89F09',

    lf : 'http://www.lfcorp.com/ko/assets/images/share/share_img.png'

  }   

});

=========== HTML ===========

<div id="app">

    <h1>Hello, {{ name }}</h1>

    <h2>{{ Date() }}</h2>

    <img :src="mark ? gs : lf"/>   

  </div>

===========================

 

(주의)==> value 처럼 {{}} 이런걸 사용할줄 알았는데 저렇게 사용하면 오히려 error발생

 

 

  • v-for : 동적 데이터를 렌더링 할때 사용한다.

=========== Script ===========

// 새로운 뷰를 정의합니다

var app = new Vue({

  el: '#app', // 어떤 엘리먼트에 적용을 정합니다

  // data 해당 뷰에서 사용할 정보를 지닙니다

  data:{

    todos: [

      { text: 'Vue.js 튜토리얼 작성하기' },

      { text: 'Webpack2 알아보기' },

      { text: '사이드 프로젝트 진행하기' }

    ]

  }

});

=========== HTML ===========

<div id="app">

    <h2> 오늘 할일 </h2>

    <ul>

      <li v-for="(todo, index) in todos">

        {{index + 1}}번쨰, {{todo.text}}

      </li>

    </ul>

  </div>

===========================

 

  • v-model : 양방향 데이터 바인딩

=========== Script ===========

// 새로운 뷰를 정의합니다

var app = new Vue({

  el: '#app', // 어떤 엘리먼트에 적용을 정합니다

  // data 해당 뷰에서 사용할 정보를 지닙니다

  data:{

    name : 'silver bell',

    isGs : true,

    gs : 'https://t1.daumcdn.net/cfile/tistory/1523C2044B42D89F09',

    lf : 'http://www.lfcorp.com/ko/assets/images/share/share_img.png'

  }

});

=========== HTML ===========

<div id="app">

    <h1>Hello, {{ name }}</h1>

    <h3><input type="checkbox" v-model="isGs"/>우리회사</h3>

    <img v-bind:src="isGs ? gs : lf"/>

</div>

===========================

 

  • v-on : 이벤트 핸들링

=========== Script ===========

var app = new Vue({

  el: '#app', 

  data: {

    number: 0

  },

  // app 인스턴스를 위한 메소드들

  methods: {

    increment: function() {

      // 인스턴스 내부의 데이터모델에 접근 ,

      // this 사용한다

      this.number++;

    },

    decrement: function() {

      this.number--;

    }

  }

});

=========== HTML ===========

<div id="app">

    <h1>카운터: {{ number }}</h1>

    <button v-on:click="increment">증가</button>

    <button @click="decrement">감소</button>

</div>

===========================

 

==> 이벤트 핸들링을 걸기위한 디렉티브는 v-on이지만 @로 대체가 가능하다.

/*

* 기간 검색 버튼 css 처리

*/

$('.date_search li').on('click', function() {

$('.date_search button').removeClass('on');

var $this = $(this);

$this.find('button').addClass('on');

});

'언어 > javascript' 카테고리의 다른 글

[문자열 조작 함수] split / reverse / join  (0) 2019.05.30

Sample.


1
2
3
4
-- 1달 더해서 뒷자리 22일로 맞추기
SELECT
TO_DATE(TO_CHAR(ADD_MONTHS(SYSDATE, 1), 'YYYYMM'|| '22''YYYYMMDD')
FROM dual;
cs


Ps. 날짜 계산함수 참고

http://itpsolver.com/%EC%98%A4%EB%9D%BC%ED%81%B4-%EB%82%A0%EC%A7%9C-%EA%B4%80%EB%A0%A8-%ED%95%A8%EC%88%98-%EB%85%84-%EC%9B%94-%EC%9D%BC-%EB%8D%94%ED%95%98%EA%B8%B0-%EB%B9%BC%EA%B8%B0-%EB%93%B1%EB%93%B1/


'cs > db' 카테고리의 다른 글

[oracle] SUBSTR, INSTR 문자열 짜르기  (3) 2020.10.13
[oracle]ORA-00918 : 열의 정의가 애매합니다.  (0) 2020.10.07

+ Recent posts