2018年12月29日 星期六

node.js java 連用(g8 王)

const http = require("http");
const net = require("net");

const host = '127.0.0.1';
const port = 8082;

let count = 0;

http.createServer(function (req, res) {
    debugger;
    count++;

    req.on('data', function(){
        debugger;
    });

    req.on('end', async function () {
        debugger;

        console.log('count(%d)', count);
        let data;
        data = await getJavaData(count);

        res.writeHead(200, { 'Content-Type': 'text/html' });

        let content = `<p>${data}</p>`;
        res.end(content);
    });

}).listen(3000);

//======================================
function getJavaData(count) {
    return new Promise(function (res, rej) {
        let data = '';
        let time = 0;

        const client = net.connect(port, host, function () {
            console.log('java connect...');
        });

        client.on('data', function (_data) {
            if (time++ == 0) {
                data = _data.toString();
                console.log('java count(%s) data(%s) data.length', count, data, data.length);
            }
        });

        client.on('end', function () {
            console.log('java end...');
            res(data);
        });
    });
}
//////////////////////////////////////////////////////////////////////////////////////
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package test_5;

import java.io.IOException;
import java.io.PrintStream;
import java.net.*;
import static java.lang.System.out;

/**
 *
 * @author xman
 */
public class Socket_1 {
   
    ServerSocket ss;
    Socket socket;
   
    static int port = 8082;
   
    public Socket_1() throws Exception {
       
            ss = new ServerSocket(port);
            while(true){
                socket = ss.accept();
                out.println("connect");
                PrintStream ps = new PrintStream(socket.getOutputStream());
                ps.println("i am java");
                ps.close();
                socket.close();
                out.println("disconnect");
            }
    }
   
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
       
        try{
        new Socket_1();           
        }catch(Exception e){
            out.println(e.toString());
        }
    }   
}

2018年12月25日 星期二

JSON.stringify 各種數據的顯示

--------------
// Int8Array
'{"0":1,"1":2,"2":3}'
[object Int8Array]
Int8Array
--------------
// Symbol
undefined
[object Symbol]
Symbol
--------------
// Map
'{}'
[object Map]
Map
--------------
// Set
'{}'
[object Set]
Set
--------------
// RegExp
'{}'
[object RegExp]
RegExp
--------------
// Date
'"2018-12-26T07:26:30.486Z"'
[object Date]
Date
--------------
// NaN
'null'
[object Number]
Number
--------------
// Infinity
'null'
[object Number]
Number
--------------
// null
'null'
[object Null]
Null
--------------
// undefined
undefined
[object Undefined]
Undefined
--------------
// {}
'{}'
[object Object]
Object

2018年12月22日 星期六

java promise

https://my.oschina.net/andylucc/blog/608499

http://ifeve.com/promise-future-callback/

https://github.com/hprose/hprose-java/wiki/%E5%BC%82%E6%AD%A5%E7%BC%96%E7%A8%8B%E2%80%94%E2%80%94Promise

https://juejin.im/post/5b126065e51d4506bd72b7cc

https://www.infoq.cn/article/design-patterns-promise https://www.cnkirito.moe/future-and-promise/


interface Closure<E, T> {
    public T callback(E in);
  
    public void error(Error err);
}


public class Promise<E> {
       
    protected int status = 0;   
    protected ArrayList<Closure> jobList = new ArrayList<>();
    protected Closure<Promise, Void> job;
    protected E data;
   
    public Promise(Closure job){
        this.job = job;

        // 暴露 resolve, reject
        this.job.callback(this);
    }

    private Promise() {
       
    }
   
    public void resolve(E e){
       
    }
   
    public void reject(String err){
       
    }
   
    protected void reject(Error err){
       
    }
   
    public Promise done(Closure c){
       
        return (new Promise<E>());
    }
   
    public Promise error(Closure c){
       
        return (new Promise<E>());
    }   
}


2018年12月21日 星期五

java 非同步做法

public interface Callback<T, E> {

    // in: 回傳的資料
    public void back(T in);
  
    // 錯誤時要做的事
    // err 錯誤訊息
    public void error(E err);
}
//----------------------------------------

public class Server_1 {

    public Thread asyncGetData(Callback callback) {
        out.println("server start");
        Thread th_1 = new Thread(() -> {
            int time = (int) (Math.random() * 5000);
          
            out.printf("server thread start(%s)\n", time);
            try {
                Thread.sleep(time);
              
                // 回傳資料
                callback.back(time);
                out.printf("server thread end(%s)\n", time);
            } catch (InterruptedException ex) {
                callback.error(ex);
            }
        });
      
        th_1.start();

        return th_1;
    }
}
//----------------------------------------
public class Client_1 {

    // 資料交換用
    int switchData_int;

    public void getData(){
        out.println("client.getData()");
        Server_1 server_1 = new Server_1();
        int gg;
        Thread th_1 = server_1.asyncGetData(new Callback<Integer, Error>() {
            @Override
            public void back(Integer in) {
                out.println("callback.back");

                // 閉包只適用於套嵌的 class
                Client_1.this.switchData_int = in;
            }

            @Override
            public void error(Error err) {

            }
        });
        try {
            th_1.join();
        } catch (InterruptedException ex) {
            out.println(ex);
        }
        out.printf("result(%s)\n------------\n", this.switchData_int);

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Client_1 cl = new Client_1();
        cl.getData();
        cl.getData();
    }

}

2018年12月19日 星期三

promise 時序性問題

let p = new Promise((res)=>{
    console.log('a');
    res();
});

p.then(()=>{
    // 非同步
    console.log('b');
})

console.log('c');

=> a, c, b

2018年12月18日 星期二

javascript 另一種模板編組

function compile(template) {
    const evalExpr = /<%=(.+?)%>/g;
    const expr = /<%([\s\S]+?)%>/g;
    template = template.replace(evalExpr, '`); \n echo( $1 ); \n echo(`');
    template = template.replace(expr, '`); \n $1 \n echo(`');
    template = 'echo(`' + template + '`);';

    console.log(template);

    let script =
        `let output = "";
            function echo(html){
            output += html;
            }       
        ${template}
        return output;`;
    return new Function(script);
}


let content = "<ul>\
    <% for(let i=0; i < 4; i++){ %>\
        <li><%= i %>--${i*2}</li>\
    <% } %>\
</ul>";

let res = compile(content);
console.log(res());
console.log('--------------------');
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
https://johnresig.com/blog/javascript-micro-templating/

function compile(template) {
    let functionStr = compile_1(template);

    functionStr = "data = data || {};\n\
        for(let k in data){\n\
            let command = 'var '+ k + '= data[\"'+k+'\"];';\n\
            eval(command);\n\
        }\n\
    " + functionStr;

    console.log(functionStr);
    let fun = new Function('print', 'data', functionStr);

    function print(html) {
        return html;
    }

    return (fun).bind(null, print);
}

function compile_1(template) {
    const expr = /([\s\S]*?)<%([\s\S]+?)%>/g;
    const evalExpr = /([\s\S]*?)<%=([\s\S]+?)%>/g;

    reg_1 = /<%[^=-][\s\S]+?%>/;
    reg_2 = /<%=[\s\S]+?%>/;
    reg_3 = /<%-[^-][\s\S]+?%>/;

    let reg = [];
    reg.push("(" + reg_1.source + ")");
    reg.push("(" + reg_2.source + ")");
    reg.push("(" + reg_3.source + ")");
    reg = reg.join("|");
    reg = `([\\s\\S]*?)(?:${reg})`;
    console.log(reg);
    reg = RegExp(reg, 'g');

    let source = "let source = [];\n";
    template = template.replace(reg, function (m, g1, g2, g3, g4) {
        debugger;
        if (g1) {
            source += `source.push(\`${g1}\`);\n`;
        }

        if (g2) {
            // <% %>
            g2 = g2.replace(/%>$/, '').replace(/^<%/, '');
            source += `\n${g2}\n`;
        } else if (g3) {
            // <%= %>
            g3 = g3.replace(/%>$/, '').replace(/^<%=/, '');
            source += `source.push(print(${g3}));\n`;
        } else if (g4) {
            // <%- %>
            g4 = g4.replace(/%>$/, '').replace(/^<%-/, '');
            source += `source.push(print(${g4}));\n`;
        }

        return '';
    });

    if (template) {
        source += `source.push(\`${template}\`);\n`;
    }

    source += 'return (source.join(""));\n';

    return source;
}


let content = "<ul>\
    <% for(let i=0; i < a.length; i++){ %>\
        <li><%= i*2 %>--${a[i]*2}</li>\
    <% } %>\
</ul>";


let res = compile(content);

console.dir(res);

2018年11月21日 星期三

json deepCopy

// 比 JSON.parse(JSON.stringify(data)) 還略慢

module.exports = deepCopy;

let jobList = [];

// for test
// 與 JSON.stringify() 對比速度用
function deepCopy(value) {
    // debugger;

    let dataSet = new DataSet(value);
    jobList.push(dataSet);

    let index = 0;

    while ((dataSet = jobList[index++]) != null) {
        // debugger;

        let _value = dataSet.originalValue;

        if (Array.isArray(_value)) {
            for (let i = 0; i < _value.length; i++) {
                let v = _value[i];
                let ds = new DataSet(v, dataSet, i);
                jobList.push(ds);
            }

        } else if (typeof (_value) == "object") {
            for (let k in _value) {
                let v = _value[k];
                let ds = new DataSet(v, dataSet, k);
                jobList.push(ds);
            }
        } else {
            continue;
        }
    }
    //-----------------------
    let res;
    let d;

    while ((d = jobList.pop()) != null) {
        res = d;
        d.solve();
    }

    return res.value;
}
//======================================

function DataSet(v, p, k) {

    this.parent; // DataSet
    this.parentKey;
    this.value;
    this.originalValue;

    this.__construct(v, p, k);
}

(function () {
    this.__construct = function (v, p, k) {

        this.originalValue = v;

        if (p) {
            this.parent = p;
            this.parentKey = k;
        }

        this._makeValue();
    };
    //--------------------------------------
    this._makeValue = function () {
        if (Array.isArray(this.originalValue)) {
            this.value = [];
        } else if (typeof (this.originalValue) == "object") {
            this.value = {};
        } else {
            this.value = this.originalValue;
        }
    };
    //--------------------------------------
    this.solve = function () {

        if (this.parent == null) {
            return;
        }

        let data = this.parent.value;
        data[this.parentKey] = this.value;

        this._destory();
    };
    //--------------------------------------
    this._destory = function () {
        this.parent = undefined;
        this.parentKey = undefined;
        this.value = undefined;
        this.originalValue = undefined;
    };
}).call(DataSet.prototype);


2018年11月20日 星期二

worker 與 java 執行續的不同

worker 父執行緒與子執行緒並不會交叉執行


let child = new Worker("./child_1.js");
        let it;

        child.onmessage = function(e) {

            let data = e.data;
            console.log(`child ${data.index}`);

            // 確保 parent loop 與 child 幾乎同時執行
            it.next();
        };

        function* parentLoop(){

            for (var i = 0; i < 100; i++) {
                console.log(`parent ${i}`);
            }

            console.dir("parent finish");
        }

        function click() {
            it = parentLoop();
            child.postMessage({});
        }
-----------------------------------------------------------------
onmessage = function(oEvent) {

    for (var i = 0; i < 100; i++) {
        postMessage({index:i});
    }

};

node.js process.nextTick 與 setImmediate() 差異



a();
process.nextTick(b);
process.nextTick(c);
d();


function a(){
    console.log("a start");
    setTimeout(() => {
        console.log("a end");
    }, 0)
}

function b(){
    console.log("b start");

    setTimeout(() => {
        console.log("b end");
    }, 0)
}

function c(){
    console.log("c start");

    setTimeout(()=>{
        console.log("c end");
    }, 0);
}

function d(){
    console.log("d start");
    setTimeout(() => {
        console.log("d end");       
    }, 0);
}
-----------------
a start
d start
b start
c start
a end
d end
b end
c end

///////////////////////////////////////////////////////////////////


a();
setImmediate(b);
setImmediate(c);
d();




function a(){
    console.log("a start");
    setTimeout(() => {
        console.log("a end");
    }, 0)
}

function b(){
    console.log("b start");
    setTimeout(() => {
        console.log("b end");
    }, 0)
}

function c(){
    console.log("c start");

    setTimeout(()=>{
        console.log("c end");
    }, 0);
}

function d(){
    console.log("d start");
    setTimeout(() => {
        console.log("d end");       
    }, 0);
}
-----------------
a start
d start
a end
d end

b start
c start
b end
c end















2018年11月13日 星期二

好文分享

https://ingramchen.io/blog/2017/07/enter-another-world-bike.html

java 從網址取得 json data 並解析


package test_4;

import org.json.*;
import java.net.*;
import java.io.*;
import static java.lang.System.out;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author xman
 */
public class T_1 {

    public static String getURLContent(String urlPath) throws MalformedURLException, IOException {
        String content = "";
        HttpURLConnection connection = null;
        BufferedReader in;

        URL url = null;

        url = new URL(urlPath);

        URLConnection urlConnection = url.openConnection();

        if (urlConnection instanceof HttpURLConnection) {
            connection = (HttpURLConnection) urlConnection;
        } else {
            System.out.println("请输入 URL 地址");
            return content;
        }
        in = new BufferedReader(
                new InputStreamReader(connection.getInputStream()));

        String current;
        while ((current = in.readLine()) != null) {
            content += current;
        }

        return content;
    }

    public static void main(String[] args) throws Exception {
        String htmlContent = getURLContent("http://localhost:8081/test_1/JSON/t_1.php");

        // out.println(htmlContent);
        JSONObject j;

        j = new JSONObject(htmlContent);

        Iterator<String> it = j.keys();;

        while (it.hasNext()) {
            String key = it.next();

            Object o_1 = j.get(key);
            out.printf("(%s)=>(%s)\n", key, o_1.toString());
        }
    }
}

java 閉包 範例

package test_4;

import static java.lang.System.out;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author xman
 */
public class T_2 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        int a = 5;

        T2_Closure t = (new T2_Closure<Object, Void>() {
            @Override
            public Void callback(Object in) {

                // 引用 a
                out.printf("callback(%s)\n", a);
                return null;
            }
        });

        t.callback(null);
        //------------------------------------

        T2_Query q = new T2_Query();

        q.query(new T2_Closure<T2_Query, Void>() {
            @Override
            public Void callback(T2_Query in) {

                String res = in.name + " : " + a;
                out.println(res);
                return null;
            }
        });
    }
}
//--------------------------------------
// 閉包

interface T2_Closure<T, E> {

    public E callback(T in);
}

//--------------------------------------

class T2_Query {

    String name = "xyz";

    void query(T2_Closure closure) {

        Thread th = new Thread(() -> {

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                out.println(e);
            }
            closure.callback(T2_Query.this);
        });

        th.start();
      
        out.println("thread start");
    }
}

java library

https://stleary.github.io/JSON-java/

https://github.com/stleary

2018年11月10日 星期六

java callback


/**
 *
 * @author xman
 */
public class Tt {

    String name = "......";

    void query(Tool t) {
        t.set(this);
    }

    public static void main(String[] args) {
        Tt tt = new Tt();

        tt.query(new Tool<Tt>() {
            public void set(Tt o) {
                out.println(o.name);
            }
        });

        tt.query((o) -> {
            // error
            out.println(o.name);
        });
    }
}

interface Tool<T> {

    public void set(T in);
}

java 非同步呼叫 callback




public class Ajax_1 {

    Callback callback;

    String name;

    void query(Callback callback) {
        this.callback = callback;
      
        // 非同步
        Thread t = new Thread(() -> {
           
            // 取得查詢
            String name = (new SyncSqlQuery()).query();
            Ajax_1.this.name = name;
            Ajax_1.this.callback.callback();
        });

        t.start();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Ajax_1 a = new Ajax_1();
        int x = 5;
       
        a.query(() -> {
            // 及時命令
            out.println(a.name);
        });
       
       
        a.query(new Callback(){
            public void callback(){
                // 及時命令
                out.println(a.name);
            }
        });

    }

}
//-------------------------------------------------------

public interface Callback {
    void callback();
}
//-------------------------------------------------------
public class SyncSqlQuery {
    public static int id = 0;
   
    String query(){
       
        return "SyncSqlQuery_" + id++;
    }
}
//////////////////////////////////////////////////////////////////////////

/**
 *
 * @author xman
 */
public class Ajax_1 {

    String name;

    void query(Callback callback) {       

        Thread t = new Thread(() -> {
           
            // 取得查詢
            String name = (new SyncSqlQuery()).query();
            Ajax_1.this.name = name;
        });

        t.start();
        try {
            t.join();
        } catch (InterruptedException ex) {
            out.println(ex);
        }

        callback.callback();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Ajax_1 a = new Ajax_1();
        int x = 5;
       
        a.query(() -> {
            out.println(a.name);
        });
       
       
        a.query(new Callback(){
            public void callback(){
                out.println(a.name);
            }
        });
    }
}

java inner-class 閉包

// 運用 innerClass

public class T_4 {

    String name;

    String getName() {
        return name;
    }
    //----------------------------
    class A {
        public void setName(String name) {
            T_4.this.name = name;
        }
    }
    //----------------------------
    public static void main(String[] args) {
        T_4 t = new T_4();
        T_4.A a = t.new A();

        a.setName("Xman");
        out.println(t.getName());
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////
// 運用 lambda
// 比較方便偷懶

interface Callback {
    // callback 內容隨你寫....讚
    public void callback(String name);
}
//-------------------------------------------
public class T_4 {

    String name;

    String getName() {
        return name;
    }

    // 送出一個 callback
    // 來設定 name
    Callback getCallback() {

        // lambda 生成一個 匿名 class implements Callback
        return ((name) -> {
            T_4.this.name = name;
        }
);
    }

    // ----------------------------
    public static void main(String[] args) {
        T_4 t = new T_4();

        // 藉由 callback 設定 t
        t.getCallback().callback("Xyz");

        out.println(t.getName());
    }
}

2018年11月9日 星期五

java繼承 與變數型態 間的問題

public class T_1 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        T_1_B b = new T_1_B();
        b.showName();

        T_1_A a = b;

        a.showName();

        try {
            a.getName(); // error
        } catch (Exception e) {
            out.println(e);
        }

    }
}
//--------------------------------
class T_1_A {

    String name = "G";

    void showName() {
        out.printf("A(%s)\n", name);
    }
}
//--------------------------------
class T_1_B extends T_1_A {

    void showName() {
        String _name = this.getName();
        out.printf("B(%s)\n", name);
    }

    String getName() {
        return name;
    }
}

2018年11月8日 星期四

各語言繼承的不同

java 與眾不同

public class T_8 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        T8_A a;
        T8_B b;
       
        a = new T8_B();       
        out.println(a.getName());
       
        b = (T8_B)a;
        out.println(b.getName());
    }
   
}

class T8_A{
    String name = "A";
   
    public String getName(){
        return name;
    }
}

class T8_B extends T8_A{
    String name = "B";
}
// 答案都是 A
----------------------------------------------------------------------
<?php

class A {

    public $name = "A";

    public function getName() {
        return $this->name;
    }

}

class B extends A {

    public $name = "B";

}

$b = new B();
printf("%s", $b->getName());

// 答案是 B
----------------------------------------------------------------------
function A(){
    this.name = "A";
}

(function(){
    this.getName = function(){
        return this.name;
    };
}).call(A.prototype);
//-------------------------------
function B(){
    A.call(this);
    this.name = "B";
}
B.prototype = Object.create(A.prototype);
//-------------------------------
console.log((new B()).getName());

// 答案是 B
----------------------------------------------------------------------

class A:
    def __init__(self):
        self.name = "A"

    def getName(self):
        return self.name;

class B(A):
    def __init__(self):
        self.name = "B"

b = B()
print("%s"%b.getName())

// 答案是 B
----------------------------------------------------------------------

2018年11月6日 星期二

java 犯行

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package test_4;

import static java.lang.System.out;

class T_4_A {

    String name = "A";

    public T_4_A() {

    }

    public T_4_A(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class T_4_B extends T_4_A {

    public String name = "...B";

    public T_4_B() {
        super("B");
    }

    public T_4_B(String name) {
        super(name);
    }
}

class T_4_C extends T_4_B {

    public String name = "...C";

    public T_4_C() {
        super("C");
    }

    public T_4_C(String name) {
        super(name);
    }
}
//==============================================================================

class T_4_Bag<T> {

    public int set_index = 0;
    public int get_index = 0;
    public T[] content;

    T_4_Bag() {
        this.content = (T[]) (new Object[10]);
    }

    void add(T t) {
        if (set_index == (content.length - 1)) {
            throw new Error("bag full");
        }
        content[set_index++] = t;
    }

    Boolean next() {
        if (get_index < set_index && content[get_index] != null) {
            return true;
        }
        return false;
    }

    T result() {
        return content[get_index++];
    }
}
//==============================================================================

/**
 *
 * @author xman
 */
public class T_4 {

    public static void test_1() {
        T_4_Bag<T_4_A> bag = new T_4_Bag<>();

        bag.add(new T_4_A());

        T_4_Bag<? super T_4_B> bag_1 = bag;

        // bag_1.add(new T_4_A()); // error
        bag_1.add(new T_4_B());

        while (bag_1.next()) {
            T_4_A o = (T_4_A) (bag_1.result());
            out.printf("(%s)=>(%s)\n", o.name, o.getName());
        }
    }
    //--------------------------------------
    public static void test_2() {
        T_4_Bag<T_4_B> bag = new T_4_Bag<>();

        bag.add(new T_4_B());

        T_4_Bag<? super T_4_B> bag_1 = bag;
      
        bag_1.add(new T_4_B());
        bag_1.add(new T_4_C());

        while (bag_1.next()) {
            T_4_B o = (T_4_B) (bag_1.result());
            out.printf("(%s)=>(%s)\n", o.name, o.getName());
        }
    }
    //--------------------------------------
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // test_1();
        test_2();
    }

}

2018年11月3日 星期六

java 泛型 exam


package test_1.t1;

/**
 *
 * @author xman
 */
public class T_4 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Container<A> c_1 = new Container<A>();
        c_1.add(new B());
        c_1.add(new C());

        Container<? extends A> c_2 = c_1;

        A a_1;

        for (int i = 0; i < 2; i++) {
            a_1 = c_2.get();
            System.out.println(a_1.getName());
        }
        // ------------------
        // 重設指針
        c_2.resetGetPoint();
        // ------------------
        A aa_1;

        // T 確定為 A
        Container<? super A> c_3 = c_1;

        c_3.add(new B());

        for (int i = 0; i < 3; i++) {
            aa_1 = c_2.get();
            System.out.println(aa_1.getName());
        }
    }

}

class Container<T extends A> {

    Object[] data;

    int set_index = 0;
    int get_index = 0;

    public Container() {
        data = new Object[10];
    }

    public void add(T item) {
        this.data[set_index++] = item;
    }

    public T get() {
        T item = (T) this.data[get_index++];
        return item;
    }

    public void resetGetPoint() {
        get_index = 0;
    }
}
//================================================
class A {

    String name;

    public A() {
        this.name = "A";
    }

    public A(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class B extends A {

    public B() {
        super("B");
    }

    public B(String name) {
        super(name);
    }
}

class C extends B {
    public C() {
        super("C");
    }

}

Java中對象的類型判斷

Java中對象的類型判斷


instanceof

判斷一個對象是否是一個類的實例,用Java中自帶的關鍵字instanceof似乎可以做到(僅從關鍵字名稱上可以猜測出),如下面的代碼:

public static void main(String args[]) {
    Object i = new Integer(7);
    if (i instanceof Number) {
        System.out.println("Integer i is a Number");
    } else {
        System.out.println("Integer i isn't a Number");
    }

    if (i instanceof Serializable) {
        System.out.println("Integer i is a Serializable");
    } else {
        System.out.println("Integer i isn't a Serializable");
    }

    if (i instanceof Integer) {
        System.out.println("Integer i is an Integer");
    } else {
        System.out.println("Integer i isn't an Integer");
    }

    if (i instanceof Float) {
        System.out.println("Integer i is a Float");
    } else {
        System.out.println("Integer i isn't a Float");
    }
}



類定義部分為:

public abstract class Number implements java.io.Serializable {}
public final class Integer extends Number implements Comparable<Integer> {}


運行結果:

    Console Output :
    Integer i is a Number
    Integer i is a Serializable
    Integer i is an Integer
    Integer i isn't a Float

然而好像和預期的不太一樣,能看出,使用該關鍵字不僅可以判斷對象是否是某個類的實例,甚至連該類繼承的基類和實現的接口也都能夠被識別為true,雖然這樣在邏輯上沒有任何問題,是可以把Integer當做一個Number來看來用,也當做一個Serializable來看來用,但是這樣返回的結果就沒有針對性了,太過於模糊,我們如果僅僅需要i instanceof Integer為true該怎麼做呢?
Class.equals

還好在Java有一個叫做Class的類,這是一個用來描述類信息的類,我們如果要精確判斷一個對象是否是具體的一個類的實例,可以這麼做:

public static void main(String args[]) {
    Object i = new Integer(7);
    if (i.getClass().equals(Number.class)) {
        System.out.println("Integer i is a Number");
    } else {
        System.out.println("Integer i isn't a Number");
    }

    if (i.getClass().equals(Serializable.class)) {
        System.out.println("Integer i is a Serializable");
    } else {
        System.out.println("Integer i isn't a Serializable");
    }

    if (i.getClass().equals(Integer.class)) {
        System.out.println("Integer i is an Integer");
    } else {
        System.out.println("Integer i isn't an Integer");
    }

    if (i.getClass().equals(Float.class)) {
        System.out.println("Integer i is a Float");
    } else {
        System.out.println("Integer i isn't a Float");
    }
}

2018年11月2日 星期五

java 區域變數的問題

int[] d = {5, 10, 60};

        int[] t = new int[1];
        int y; // 會有問題
       
        for (int i = 0; i < d.length; i++) {
            t[0] = d[i];
            y = d[i];
        }
       
        System.out.println("(%d, %d)",t[0], y);

2018年10月30日 星期二

about js Generator

判斷一個function 是否是generator 的方法

var x  = function * (){yield undefined;}
console.log(x.constructor.name === 'GeneratorFunction')
-------------------------------------------------------------------
The function* declaration (function keyword followed by an asterisk) defines a generator function, which returns a Generator object.
You can also define generator functions using the GeneratorFunction constructor, or the function expression syntax.

Syntax

Section

function* name([param[, param[, ... param]]]) {
   statements
}
name
The function name.
param
The name of a formal parameter for the function.
statements
The statements comprising the body of the function.

Description

Section

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.

Generators in JavaScript -- especially when combined with Promises -- are a very powerful tool for asynchronous programming as they mitigate -- if not entirely eliminate -- the problems with callbacks, such as Callback Hell and Inversion of Control.
This pattern is what async functions are built on top of.
Calling a generator function does not execute its body immediately; an iterator object for the function is returned instead. When the iterator's next() method is called, the generator function's body is executed until the first yield expression, which specifies the value to be returned from the iterator or, with yield*, delegates to another generator function. The next() method returns an object with a value property containing the yielded value and a done property which indicates whether the generator has yielded its last value as a boolean. Calling the next() method with an argument will resume the generator function execution, replacing the yield expression where execution was paused with the argument from next().
A return statement in a generator, when executed, will make the generator finished (i.e the done property of the object returned by it will be set to true). If a value is returned, it will be set as the value property of the object returned by the generator.
Much like a return statement, an error thrown inside the generator will make the generator finished -- unless caught within the generator's body.
When a generator is finished, subsequent next calls will not execute any  of that generator's code, they will just return an object of this form: {value: undefined, done: true}.

Examples

Section

Simple example

Section

function* idMaker() {
  var index = 0;
  while (index < index+1)
    yield index++;
}

var gen = idMaker();

console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
// ...

Example with yield*

Section

function* anotherGenerator(i) {
  yield i + 1;
  yield i + 2;
  yield i + 3;
}

function* generator(i) {
  yield i;
  yield* anotherGenerator(i);
  yield i + 10;
}

var gen = generator(10);

console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20

Passing arguments into Generators

Section

function* logGenerator() {
  console.log(0);
  console.log(1, yield);
  console.log(2, yield);
  console.log(3, yield);
}

var gen = logGenerator();

// the first call of next executes from the start of the function
// until the first yield statement
gen.next();             // 0
gen.next('pretzel');    // 1 pretzel
gen.next('california'); // 2 california
gen.next('mayonnaise'); // 3 mayonnaise

Return statement in a generator

Section

function* yieldAndReturn() {
  yield "Y";
  return "R";
  yield "unreachable";
}

var gen = yieldAndReturn()
console.log(gen.next()); // { value: "Y", done: false }
console.log(gen.next()); // { value: "R", done: true }
console.log(gen.next()); // { value: undefined, done: true }

Generators are not constructable

Section

function* f() {}
var obj = new f; // throws "TypeError: f is not a constructor

Generator defined in an expression

Section

const foo = function* () {
  yield 10;
  yield 20;
};

const bar = foo();
console.log(bar.next()); // {value: 10, done: false}
 
-------------------------------------------
 
The Generator object is returned by a generator function and it conforms to both the iterable protocol and the iterator protocol.

Syntax

區段

function* gen() { yield 1; yield 2; yield 3; } var g = gen(); // "Generator { }"

Methods

區段

Generator.prototype.next()
Returns a value yielded by the yield expression.
Generator.prototype.return()
Returns the given value and finishes the generator.
Generator.prototype.throw()
Throws an error to a generator (also finishes the generator, unless caught from within that generator).

Example

區段

An infinite iterator

區段

function* idMaker() {  
    var index = 0;  
    while(true) yield index++; 
}  

var gen = idMaker(); // "Generator { }" console.log(gen.next().value); // 0 

console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 // ...

Legacy generator objects

區段

Firefox (SpiderMonkey) also implemented an earlier version of generators in JavaScript 1.7, where the star (*) in the function declaration was not necessary (you just use the yield keyword in the function body). However, legacy generators support has been removed since Firefox 58 (released on January 23, 2018) (bug 1083482).

Legacy generator methods

區段

Generator.prototype.next()
Returns a value yielded by the yield expression. This corresponds to next() in the ES2015 generator object.
Generator.prototype.close()
Closes the generator, so that when calling next() an StopIteration error will be thrown. This corresponds to the return() method in the ES2015 generator object.
Generator.prototype.send()
Used to send a value to a generator. The value is returned from the yield expression, and returns a value yielded by the next yield expression. send(x) corresponds to next(x) in the ES2015 generator object.
Generator.prototype.throw()
Throws an error to a generator. This corresponds to the throw() method in the ES2015 generator object.

Legacy generator example

區段

function* fibonacci() { var a = yield 1; yield a * 2; }  

var it = fibonacci(); 

console.log(it); // "Generator { }" console.log(it.next()); // 1 

console.log(it.send(10)); // 20 console.log(it.close()); // undefined 
console.log(it.next()); // throws StopIteration (as the generator is now closed)