2022年8月11日 星期四

lambda 的 this (java8 八)

/**
 * 印 this 的時候,會調用 Object.toString()
 * 匿名類別的 this:會先調用自己匿名類別的 toString,沒有才去 Object.toString
 * Lambda 的 this:會先調用「當下」類別的 toString,沒有才去 Object.toString
 */
public class ThisTest {
    Animal a1 = new Animal() {
        @Override
        public void m(String str) {
            System.out.println(this);
        }

//        @Override
//        public String toString() {
//            return "anonymous toString";
//        }
    };

    Animal a2 = s -> System.out.println(this);

//    @Override
//    public String toString() {
//        return "this toString";
//    }

    public static void main(String[] args) {
        ThisTest thisTest = new ThisTest();
        thisTest.a1.m("xxx");
        thisTest.a1.m("aaa");
        thisTest.a2.m("ooo");
        thisTest.a2.m("bbb");
    }

    @FunctionalInterface
    public interface Animal {
        void m(String str);
    }
}


2022年7月14日 星期四

Java 的 floorMod 和 %

// System.out.println(Math.floorMod(113, 30)); // 23
System.out.println(Math.floorMod(113, -30)); // -7
System.out.println(Math.floorMod(-113, 30)); // 7
System.out.println(Math.floorMod(-113, -30)); // -23
System.out.println("-----------------------");
// System.out.println(113 % 30); // 23
System.out.println(113 % -30); // 23
System.out.println(-113 % 30); // -23
System.out.println(-113 % -30); // -23
System.out.println("=======================");
// System.out.println(Math.floorDiv(113, 30)); // 3
System.out.println(Math.floorDiv(113, -30)); // -4
System.out.println(Math.floorDiv(-113, 30)); // -4
System.out.println(Math.floorDiv(-113, -30)); // 3
System.out.println("-----------------------");
// System.out.println(113 / 30); // 3
System.out.println(113 / -30); // -3
System.out.println(-113 / 30); // -3
System.out.println(-113 / -30); // 3

除數和被除數全正數和全負數時,% 和 mod 一模一樣

※全負數時,除法是負負得正;

※有負數時, % 的正負號看左邊,mod 的正負號看右邊,如 -113 % -30,-113 是左邊;-30 是右邊,一正一負時也是一樣

※113 / 30 是 3...23

floorDiv 時,一正一負為負,(3 + 1) * -1 = -4,固定加1乘-1

floorMod 時,30 - 23 = 7,然後看 30 是正或負,7 的正負號就和它一樣

目前不知道 mod 這樣有什麼用




 

2022年2月17日 星期四

檢查服務是否啟動、grep、sed、awk

檢查服務是否啟動

lsof -i:8080

netstat -lntup |grep 8080

ss -lntup |grep 8080

ps -ef |grep 8080



grep 

過濾文字

-A 之前x行(不包括搜尋的行)

-B 之後x行(不包括搜尋的行)

-C 前後x行(不包括搜尋的行)

-c 有幾行,類似 wc -l 的功能

-i 忽略大小寫

-w word,單字匹配

-v 回傳相反的匹配


grep -A3 5 fileName:找到 5 後,將前3行顯示出來,所以總共會顯示 4 行

seq 10 |grep -A3 5   ==> 5~8

seq 10 |grep -B3 5   ==> 2~5

seq 10 |grep -C3 5   ==> 2~8


seq 20 |grep 5 |wc -l

seq 20 |grep -c 5


grep -i a test.txt


seq 50 |grep 5

seq 50 |grep -w 5


seq 20 |grep -v 5




sed

針對行的增刪改查,stream edit 的縮寫


-n:sed 會一行一行執行,預設每行都會輸出,所以匹配到的會出現兩次,而加這個只會將匹配成功的輸出

-i:顯示的結果,預設不會覆蓋原檔案,如果要覆蓋要加這個參數

-r -E:加上正則表達式支援


增刪改查

c a i:replace想成 ce的c/append/insert

d:delete

s:substitute

p:print


p:

'3p' 印出第3行

'1,5p' 印出1~5行

'/xxx/p' 找 xxx

'/10:00/,/11:00/p' 找 10:00~11:00 之間的資料


增刪改查範例:

sed -n '/7/,/10/p' test.txt

sed '/7/,/10/d' test.txt // 加 -n 會看不到結果,每次的7~10都會刪除

sed 's/a/aaa/' test.txt // s寫在前面,s/a/aaa/、s#a#aaa#,分隔符不要太奇怪都可以

sed 's#[0-9]##g' test.txt // 將數字取代成空,但仍然有換行,最後不加 g,只會取代每行的第一個數字

sed '6a xxxxxx' test.txt // 在第6行之後加一行 xxxxxx 

sed '6i xxxxxx' test.txt // 在第6行之前加一行 xxxxxx 

sed '6c xxxxxx' test.txt // 取代第6行,變成 xxxxxx 


awk

發明人的名字第一個字母組成的


record:行(左右),預設 \n,-v RS 可改

field:列(上下),預設空隔,-F 或 -v FS 可改


$數字:第x列,$0是整行

NF:最後一列的數字,可以加減,但要用圓括號包起來

NR:行號

-F分隔符

FS:-v FS=分隔符,給 awk 的分隔符,相當於 -F,預設是空格

OFS:-v OFS=分隔符,awk 返回結果的分隔符,預設是空格

RS:-v RS=換行符,預設 \n

ORS:-v ORS=換行符,預設 \n

print 會換行

printf 不會換行


NR

Number of Record

NR==1 取出第一行

NR >=1 && NR <= 5 取出 1~5 行,還有 == != 可用

awk 'NR >= 12 && NR <= 15' test.txt


假設有一行 1,2,3,4,5,6,7,8,9,10

awk -F, 'NR==1{print $NF}' test.txt // 取第一行,然後以,分隔,再取最後一列,所以是10

awk -F, 'NR==1{print $(NF-1)}' test.txt // 取到數第二列

ls -l |awk '{print $5, $NF}' |column -t // 取第五列和最後一列,並排版

ls -l |awk '{for(i=5;i<=NF;i++){printf $i" "};printf "\n"}' |column -t // 取第五列到最後一列


正則

awk '$10~/^1/{print $10}' fileName    // 第 10 個欄位是 1 開頭就印出來

~ 包含

!~ 不包含

^$ 空

//,//

//,//{print $2}


BEGIN、END

BEGIN{} 內容在 awk 讀檔案之前執行

END{} 內容在 awk 讀檔案之後執行


seq 100 |awk 'BEGIN {pring 0} {sum=sum+$1; print sum} END{print "finish"}'

印出 0~100 相加的過程,BEGIN 和 END 可以只用一個



陣列

非數字要用字串包起來

awk 'BEGIN{x[0]=123; x[1]="xxx"; print x[0], x[1]}'

awk 'BEGIN{x[0]=123; x[1]="xxx"; for(i in x) print x[i]}'