Total Pageviews

2014/12/25

Apache CollectionUtils 應用

Assume we had 2 list data
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
      //create a value object and add into list1
        UnpaymentDataVo vo1 = new UnpaymentDataVo();
        vo1.setDebtType("B");
        vo1.setBudgetCode(new BigDecimal(1));
        vo1.setDebitName("總預算");
        vo1.setDamt(new BigDecimal(5156340000000L));
        vo1.setCamt(new BigDecimal(3489209150690L));
        vo1.setIamt(new BigDecimal(69360745739L));
        vo1.setRamt(new BigDecimal(1597620103571L));

        List<UnpaymentDataVo> list1 = new ArrayList<UnpaymentDataVo>();
        list1.add(vo1);

 //create 2 value objects and add into list2
        UnpaymentDataVo vo2 = new UnpaymentDataVo();
        vo2.setDebtType("A");
        vo2.setBudgetCode(new BigDecimal(2));
        vo2.setDebitName("易淹水地區水患治理計劃第2期特別預算");
        vo2.setDamt(new BigDecimal(7500000000L));
        vo2.setCamt(new BigDecimal(0));
        vo2.setIamt(new BigDecimal(637500000L));
        vo2.setRamt(new BigDecimal(7500000000L));

        UnpaymentDataVo vo3 = new UnpaymentDataVo();
        vo3.setDebtType("A");
        vo3.setBudgetCode(new BigDecimal(1));
        vo3.setDebitName("振興經濟擴大公共建設特別預算");
        vo3.setDamt(new BigDecimal(204400000000L));
        vo3.setCamt(new BigDecimal(0));
        vo3.setIamt(new BigDecimal(14465750000L));
        vo3.setRamt(new BigDecimal(204400000000L));

        List<UnpaymentDataVo> list2 = new ArrayList<UnpaymentDataVo>();
        list2.add(vo2);
        list2.add(vo3);

 //print list1 and list2
        log.debug("list1=" + list1.toString());
        log.debug("list2=" + list2.toString());

The data structure looks like this:
1
2
3
- list1=[UnpaymentDataVo(debtType=B, budgetCode=1, debitName=總預算, damt=5156340000000, camt=3489209150690, iamt=69360745739, ramt=1597620103571)]
- list2=[UnpaymentDataVo(debtType=A, budgetCode=2, debitName=易淹水地區水患治理計劃第2期特別預算, damt=7500000000, camt=0, iamt=637500000, ramt=7500000000), 
         UnpaymentDataVo(debtType=A, budgetCode=1, debitName=振興經濟擴大公共建設特別預算, damt=204400000000, camt=0, iamt=14465750000, ramt=204400000000)]


If you would like to find out the data from list2 which condition is debt_type='A' and budget_code=2
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
        // find out the data from list2 which condition is debt_type='A' and budget_code=2
        List<UnpaymentDataVo> searchResult = new ArrayList<UnpaymentDataVo>();
        CollectionUtils.select(list2, new Predicate() {
            @Override
            public boolean evaluate(Object object) {
                UnpaymentDataVo vo = (UnpaymentDataVo) object;
                return "A".equals(vo.getDebtType())
                        && vo.getBudgetCode().compareTo(new BigDecimal(2)) == 0;
            }
        }, searchResult);

        log.debug("searchResult = " + searchResult.toString());

The search result looks like this:
1
2
- searchResult = [UnpaymentDataVo(debtType=A, budgetCode=2, debitName=易淹水地區水患治理計劃第2期特別預算, damt=7500000000, camt=0, iamt=637500000, ramt=7500000000), 
]

If you would like to get  a Collection containing the union of list1 and list2
1
2
3
4
        // Returns a Collection containing the union of the given Collections
        List<UnpaymentDataVo> unionResult = (List<UnpaymentDataVo>) CollectionUtils.union(list1,
                list2);
        log.debug("unionResult = " + unionResult.toString());

The union result looks like this:
1
2
3
- unionResult = [UnpaymentDataVo(debtType=A, budgetCode=2, debitName=易淹水地區水患治理計劃第2期特別預算, damt=7500000000, camt=0, iamt=637500000, ramt=7500000000), 
                 UnpaymentDataVo(debtType=A, budgetCode=1, debitName=振興經濟擴大公共建設特別預算, damt=204400000000, camt=0, iamt=14465750000, ramt=204400000000), 
   UnpaymentDataVo(debtType=B, budgetCode=1, debitName=總預算, damt=5156340000000, camt=3489209150690, iamt=69360745739, ramt=1597620103571)]


If you would like to return a collection which contains unionResult - list2
1
2
3
4
        // Returns a new Collection containing a - b.
        List<UnpaymentDataVo> subtractResult = (List<UnpaymentDataVo>) CollectionUtils.subtract(
                unionResult, list2);
        log.debug("subtractResult = " + subtractResult.toString());

The subtract result looks like this:
1
- subtractResult = [UnpaymentDataVo(debtType=B, budgetCode=1, debitName=總預算, damt=5156340000000, camt=3489209150690, iamt=69360745739, ramt=1597620103571)]



Reference
[1] https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.1/org/apache/commons/collections/CollectionUtils.html#subtract(java.util.Collection, java.util.Collection)

[Oracle] Use to_char to format date column

Question
I have two column, ISSUE_DATE & DUE_DATE, with date data type.
But I only new YYYYMM not YYYYMMDD in report, how to format them?

Answer
We can use TO_CHAR to fulfill this requirement.

The to_char syntax is:
TO_CHAR( value, [ format_mask ], [ nls_language ] )

  • value can either be a number or date that will be converted to a string.
  • format_mask is optional. This is the format that will be used to convert value to a string.
  • nls_language is optional. This is the nls language used to convert value to a string.

Example.
1
2
3
4
5
6
SELECT ID, 
        DUE_DATE, 
        TO_CHAR( DUE_DATE, 'YYYYMM') FORMATED_DUE_DATE,
        ISSUE_DATE,
        TO_CHAR( ISSUE_DATE, 'YYYYMM') FORMATED_ISSUE_DATE
FROM ISSUE_MAIN



Reference
[1] http://www.techonthenet.com/oracle/functions/to_char.php

2014/12/22

市場乘數 (平均本益比)

無論是漫步華爾街或是彼得學林的學以致富的書籍中,作者都有提到不要買價格超過其實際價值的股票,強調用本益比來挑選股票的重要性。

如果想知道目前本隻本益比是偏高或偏低,可以看過去的歷史紀錄來判斷。
以中華電信為例,目前中華電信(2412)的本益比是18.05

我們可以去查一下過去五年來的最高平均、最低平均以及平均本益比的值
根據下圖的資訊,可以得知99~103年的歷年最高、最低本益比資訊,故:
  • 平均最高本益比 = (19 + 20 + 18 + 18 + 16) / 5 = 18.2
  • 平均最低本益比 =  (17 + 17 + 14 + 14 + 13) / 5 = 15
  • 平均本益比 = 16.6



由上述資訊可以看出目前中華電信本益比為18.05,屬於接近偏高

然而以上是用單支股票的方式來看,在學以致富此本書中有提到,我們也可以一次挑選多家公司,把他們的股價加起來,然後除以它們的盈餘,就可以得出一個平均本益比。在華爾街,人們用此方式計算道瓊工業指數、S&P 500指數的本益比,得出所謂的市場乘數(Market Multiple),也就是平均本益比,其代表著人們願意以多高的價格買下多少盈餘的公司。

在台灣的話,我們可以參考台灣50的成分股,以下是50檔台灣50的本日股價與EPS相關資訊:


代號 公司名稱 股價 EPS
3474 華亞科 47.60 7.10
4938 和碩 72.50 4.94
3481 群創 14.95 0.97
2330 台積電 138.50 8.82
2303 聯電 14.45 0.66
2882 國泰金 46.15 3.63
2357 華碩 335.00 27.68
1303 南亞 61.60 4.43
2883 開發金 9.83 0.68
1301 台塑 68.00 3.79
2002 中鋼 26.10 1.22
2311 日月光 39.10 2.55
2317 鴻海 88.00 8.21
1402 遠東新 30.05 2.23
2892 第一金 18.45 1.44
2880 華南金 17.40 1.30
2801 彰銀 18.00 1.36
1216 統一 48.60 2.00
1101 台泥 42.45 2.89
1102 亞泥 37.85 2.76
2382 廣達 78.50 4.88
2308 台達電 186.00 8.31
1326 台化 64.50 3.39
2886 兆豐金 24.10 2.28
2891 中信金 20.40 2.66
2325 矽品 48.20 3.50
2105 正新 71.60 5.13
2395 研華 216.00 7.44
2408 南科 73.90 10.30
2412 中華電 92.60 5.12
2409 友達 15.10 1.30
2207 和泰車 463.00 16.63
2301 光寶科 36.00 3.24
9904 寶成 38.10 2.94
2912 統一超 245.00 8.76
2354 鴻準 87.60 5.21
2474 可成 242.00 19.40
3045 台灣大 99.90 5.78
2454 聯發科 455.00 29.64
2881 富邦金 49.45 5.81
2887 台新金 12.90 1.62
4904 遠傳 69.90 3.71
2885 元大金 15.20 1.53
3008 大立光 2,325.00 113.67
2498 宏達電 136.50 1.62
2884 玉山金 19.55 1.50
2890 永豐金 12.80 1.53
6505 台塑化 66.20 3.02
5880 合庫金 18.45 1.26
2227 裕日車 327.00 20.60

上述50檔台灣50的股價total為 6785.03,盈餘的total為 390.44,把股價 (6785.03) 除以盈餘 (390.44) ,可以得到這50檔的平均本益比為17.38


Total 股價 Total 盈餘 市場乘數 (市場平均本益比)
6785.03 390.44 17.38

我們就可以拿17.38這個數字做為參考,人們願意購買的本益比的股票約為17.38,代表著人們願意以多高的價格買下多少盈餘的公司股票,若過高的話就要考慮一下了,這個或許也可以作為一個股票買賣的一個參考


Reference

[1] http://www.twse.com.tw/ch/trading/indices/twco/tai50i.php
[2] http://www.cnyes.com/twstock/profile/2412.htm
[3] http://jsjustweb.jihsun.com.tw/z/zc/zca/zca_2412.djhtm

How to Determine if the Date Format is Correct or Not in Java

Problem
We hope the date parameter should be yyyyMMdd format and only accept Western calendar system. 
If user provide a date parameter with Minguo calendar, it should return error to user.

Solution
This DateUtils class provides an isCorrectDateFormatWithWesternYear method, it will

  • return false if date format is incorrect
  • return true if date format is correct

We define the expected format in Line 24.
Set lenient to false with strict parsing, and call parse method to check the parse result.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package gov.nta.dbm.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import lombok.extern.slf4j.Slf4j;

/**
 * The Class DateUtils.
 */
@Slf4j
public class DateUtils {

    /**
     * Checks if is correct date format with western year.
     * 
     * @param dateStr
     *            the date str
     * @return the boolean
     */
    public static Boolean isCorrectDateFormatWithWesternYear(String dateStr) {
        Boolean isCollect = Boolean.FALSE;
        // instantiate SimpleDateFormat object with specific date format
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        try {
            // Specify whether or not date/time parsing is to be lenient. With lenient parsing, the
            // parser may use heuristics to interpret inputs that do not precisely match this
            // object's format. With strict parsing, inputs must match this object's format
            dateFormat.setLenient(false);
            // call parse method, return true if parse successfully, return false if fail to parse.
            dateFormat.parse(dateStr);
            isCollect = Boolean.TRUE;
        } catch (ParseException e) {
            isCollect = Boolean.FALSE;
            e.printStackTrace();
        }
        return isCollect;
    }

    /**
     * The main method.
     * 
     * @param args
     *            the arguments
     */
    public static void main(String[] args) {
        log.debug("test1=" + DateUtils.isCorrectDateFormatWithWesternYear("20141231"));
        log.debug("test1=" + DateUtils.isCorrectDateFormatWithWesternYear("1031222"));
    }

}

In main method, we input "20141231" and "1031222" to do test, and here is the test result:
1
2
3
4
5
6
15:34:00.446 [main] DEBUG gov.nta.dbm.utils.DateUtils - test1=true
java.text.ParseException: Unparseable date: "1031222"
 at java.text.DateFormat.parse(DateFormat.java:357)
 at gov.nta.dbm.utils.DateUtils.isCorrectDateFormatWithWesternYear(DateUtils.java:31)
 at gov.nta.dbm.utils.DateUtils.main(DateUtils.java:48)
15:34:00.453 [main] DEBUG gov.nta.dbm.utils.DateUtils - test1=false


Reference
[1] http://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html

2014/12/19

How to delete a branch in EGit?

Question
Assume I created a branch, DBM_CommonService_getPaymentData, to implement a new function. 

After I finished this function and commit & push to GitLab,  and GitLab project owner merged this branch into master. 

If I had switch to master and would like to delete DBM_CommonService_getPaymentData branch, how to delete it?


Answer

Step1. right click => Team => Advanced => Delete branch

Step2. Selected the branch name you want to delete => Click "OK"

See..as you right click => Team => Switch to, you won't see DBM_CommonService_getPaymentData branch anymore.

Reference

2014/12/17

How to Run Stored Procedure in Oracle SQL Developer

Problem
Assume I created a stored procedure which named PROC_FMS406R_TAB5_RPT1_STEP1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
create or replace PROCEDURE PROC_FMS406R_TAB5_RPT1_STEP1 
(
  INPUT_YYY_MM IN VARCHAR2 
, INPUT_LAST_YEAR IN VARCHAR2 
, INPUT_USER_ID IN VARCHAR2 
) AS 
BEGIN
  
  --1.5.2 計算『歲入估測分析表(含特別預算)』上一年度的一月到12月的實際數
 -- ignore execution detail

  
  
 --1.5.3 計算『歲入估測分析表(含特別預算)』上一年度的合計數
 -- ignore execution detail
  
END PROC_FMS406R_TAB5_RPT1_STEP1;


I tried to execute PROC_FMS406R_TAB5_RPT1_STEP1 in SQL worksheet


It will fail to execute and show this error message:

1
2
3
4
命令的第 2 行開始發生錯誤 -
PROC_FMS406R_TAB5_RPT1_STEP1(:INPUT_YYY_MM, :INPUT_LAST_YEAR, :INPUT_USER_ID)
錯誤報告 -
不明的命令

How to Fix This Problem
Add BEGIN before the stored procedure and add END; after the stored procedure.

1
2
3
BEGIN
PROC_FMS406R_TAB5_RPT1_STEP1(:INPUT_YYY_MM, :INPUT_LAST_YEAR, :INPUT_USER_ID);
END;


Reference
[1] http://dba.stackexchange.com/questions/57163/how-to-run-procedure-in-oracle-sql-developer

2014/12/16

Utilize Styles to Change Font Color Based on Condition in iReport

Problem
Customer ask us to change font color to red if the amount is less than zero.

It should look like this:


Solution
  • Step1. Move cursor to "Styles" and right click => Add => Style


  • Step2. Right click on "style1" => Add "Conditional Style"


  • Step3. Edit "Conditional Expression" ( apply this style if $F(amount) value is less than zero)


  • Step4. Set font color to RED


  • Step5. Owning to set font color to red, it will set line color to red as well. Hence, we need to set line color to black manually.


  • Step6. Click on $F{amount} and set "Style" to "style1" which we create and configure in Step2 ~ Step5.