java Stream流式编程
流式处理
流是一系列数据项,一次只生成一项。程序可以从输 入流中一个一个读取数据项,然后以同样的方式将数据项写入输出流。一个程序的输出流很可能是另一个程序的输入流。
流的特点
元素序列——就像集合一样,流也提供了一个接口,可以访问特定元素类型的一组有序值。
数据处理操作
流的数据处理功能支持类似于数据库的操作,以及函数式编程语言中的常用操作,如filter、map、reduce、find、match、sort等。流操作可以顺序执行,也可并行执行。
underscore流式处理的设计原理
Underscore结构
- 作用域包裹
与其他第三库一样,Underscore也通过立即执行函数 来包裹自己的业务逻辑。
目的
•避免全局污染:所有库的逻辑,库所定义和使用的变量全部被封装到了该函数的作用域中。
•隐私保护:但凡在立即执行函数中声明的函数、变量等,除非是自己想暴露,否则绝无可能在外部获得。
(function(){
// .....执行逻辑
})(this)// window
面向对象风格支持
// 两种调用方式的实现
// _.unique([1,2,3,2,1])
// 新增_([1,2,3,2,1]).unique()
var _ = function (data) {
if (!(this instanceof _)) {
return new _(data);
}
this.wrapper = data;
}
mixin
// mixin(混入)模式是增加代码复用度的一个广泛使用的设计模式。
// _.mixin(object):为 underscore 对象混入 object 具有的功能。
//源码
_.mixin = function(obj){
_.each(_.functions(obj),function(name){
var func = _[name] = obj[name];
_.prototype[name] = function(){
var args = [this._wrapped];
push.apply(args, arguments);
return chain(this, func.apply(_, args));
};
});
return _;
};
// 而在我们自己编写的源码为了易读,易于分析,进行了拆解,
// 混入方法的name名从我们的_中取到列个数组
_.posscess = function (target) {
var result = [];
for (var name in target) {
result.push(name);
}
return result;
}
//遍历循环,把每个name在回调里单独处理
var beforeHook = function (keys, callback) {
for (var i = 0; i < keys.length; i++) {
callback(keys[i]);
}
}
_.mixin = function (object) {
beforeHook(_.posscess(object), function (key) {
var func = object[key];
object.prototype[key] = function () {
var deco = [this.wrapper];
Array.prototype.push.apply(deco, arguments); // 重构 deco = [deco + arguments对应事件参数]
return model(this, func.apply(this, deco)); //1: 对象 2: 数据的结果(这块在4.链式调用有讲)
}
});
}
链接式调用
// jQuery链接式调用。
$('.div').css('color', 'red').show();
// 想要实现链式调用,通常我们会在支持链式调用的函数中返回对象本身。
var RULES = function(){
add:function(x){console.log(x); return this},
mult:function(y){console.log(y); return this}
};
RULES.add(4).mult(5);
// 但是,这样做并不优雅,这需要我们手动地在函数中添加 return this; 语句。更好的做法是我们创建一个通用函数,它能为指定的对象方法增加链式调用机制。
// _.chain():为 underscore 对象的方法增加链式调用能力。
_.chain = function (data) {
var instance = _(data);
instance._chain = true;
return instance;
}
// 写一个帮助函数 model,该函数将会判断方法调用结果,如果该方法的调用者被标识了需要链化,则链化当前的方法执行结果。
var model = function (instance, outcome) {
if (instance._chain) {
instance.wrapper = outcome;
return instance;
}
return outcome;
}
根据流式处理的设计原理编写的源码
(function (root) {
var _ = function (data) {
if (!(this instanceof _)) {
return new _(data);
}
this.wrapper = data;
}
_.unique = function (source, callback) {
var result = [];
for (let i = 0; i < source.length; i++) {
var target = callback ? callback(source[i]) : source[i];
if (result.indexOf(target) === -1) result.push(target);
}
return result;
}
_.chain = function (data) {
var instance = _(data);
instance._chain = true;
return instance;
}
var model = function (instance, outcome) {
if (instance._chain) {
instance.wrapper = outcome;
return instance;
}
return outcome;
}
_.max = function (outcome) {
outcome.push("max")
return outcome
}
_.prototype.ending = function () {
return this.wrapper;
}
_.posscess = function (target) {
var result = [];
for (var name in target) {
result.push(name);
}
return result;
}
var beforeHook = function (keys, callback) {
for (var i = 0; i < keys.length; i++) {
callback(keys[i]);
}
}
_.mixin = function (object) {
beforeHook(_.posscess(object), function (key) {
var func = object[key];
object.prototype[key] = function () {
var deco = [this.wrapper];
Array.prototype.push.apply(deco, arguments);
return model(this, func.apply(this, deco)); //1: 对象 2: 数据的结果
}
});
}
_.mixin(_);
root._ = _;
})(this);
// 两种调用方式:
console.log(_([1, 2, 3, 4, 5, 6, 7, 8, 3, 4, 5, 6, "a", "A"]).chain()
.unique(function (item) {
return typeof item === "string" ? item.toLowerCase() : item;
})
.max()
.ending()
)
console.log(_.chain([1, 2, 3, 4, 5, 6, 7, 8, 3, 4, 5, 6, "a", "A"])
.unique(function (item) {
return typeof item === "string" ? item.toLowerCase() : item;
})
.max()
.ending()
)