摘要: 这次统一看一下scala中容器类的几个方法。 Set filter()方法 filter()方法用来从Set中过滤获取含有指定特征的元素。示例代码如下: val colors1 = Set("Blue", "Green", "Red", "yellow") val filteredSet = colors1 filter (_ contains "l") println(filteredSet m... 阅读全文
posted @ 2016-09-13 22:11 robin·张 阅读(1318) 评论(0) 推荐(0) 编辑
摘要: scala的容器包括Set、List和Map。三种容器的特征和Java中一样。scala为每种容器都提供了可变和不可变两种版本,分别位于scala.collection.mutable或scala.collection.immutable包下。scala建议使用尽量使用不可变容器,尤其是在多线程环境下。并且scala默认的容器就是不变的版本。 可变容器没什么好说的,java中的容器就是。来看一个不... 阅读全文
posted @ 2016-09-11 22:50 robin·张 阅读(407) 评论(0) 推荐(0) 编辑
摘要: 先来看一下下面的内容: 2 days “ago” 5 days “from_now” 如上的内容具体应该是什么呢?不过怎么看也不像是代码。不过既然是在学代码,拿不是代码的东西出来做什么! 非要强说是代码的话,那么执行起来肯定是要报错的——因为scala的Int和RichInt,以及Integer中都没有days这样的方法: 如果说不是代码的话,那么scala中的to或until本来看起来也不像代... 阅读全文
posted @ 2016-08-28 08:18 robin·张 阅读(1195) 评论(0) 推荐(0) 编辑
摘要: trait的方法的延迟绑定就是先混入的trait的方法会后调用。这一点从上一节的实例中也可以看出来。 下面再来看一个类似的例子: abstract class Writer { def write(message: String): String } trait UpperWriter extends Writer { abstract override def write(messag... 阅读全文
posted @ 2016-08-15 22:52 robin·张 阅读(662) 评论(0) 推荐(0) 编辑
摘要: 在上一节看到了scala的在实例一级的选择性混入就不得不感叹scala在语法上的扩展性。就通过这样一个特性scala简化了很多在java中的编程概念和设计模式。 比如说在java中常用的组合,以及装饰模式。下面看个书中的例子,详细说说如何使用trait进行装饰。 假设我们要对一个人进行检查,包括信用记录、收支记录、犯罪记录和工作记录等。但是我们并不会总是都会用到所有的检查,比如要买房时会检查信用记... 阅读全文
posted @ 2016-08-14 10:34 robin·张 阅读(836) 评论(0) 推荐(0) 编辑
摘要: 继续上一节。 狗当然是人类的好朋友。但是藏獒呢?这玩意儿又蠢又笨又凶狠,肯定不能算很多人的好朋友了。其实,刚才那句话还可以修正一下下:我们接受的狗才是我们的好朋友。 用程序怎么实现呢?在java里面,可以使用组合来实现这样的逻辑,仅仅使用接口还是有些勉强的。而scala则可以在实例一级混入trait: trait Friend{ val name : String def accompan... 阅读全文
posted @ 2016-08-09 22:22 robin·张 阅读(524) 评论(0) 推荐(0) 编辑
摘要: 不知道大家对java的接口是如何理解的。在我刚接触到接口这个概念的时候,我将接口理解为一系列规则的集合,认为接口是对类的行为的规范。现在想来,将接口理解为是对类的规范多少有些偏颇,更恰当些的观点应该是:相对于类来说,接口是更深层次的抽象,虽然同时接口也起到了规定类的行为的作用。 和java的接口比起来,scala的Trait可能更具体一些。正如Trait的含义一样,它指的是一种特质,如果认为类有某... 阅读全文
posted @ 2016-08-08 22:44 robin·张 阅读(477) 评论(0) 推荐(0) 编辑
摘要: 首先要弄白闭包的概念。 教材中的说法是:闭包是一种特殊的函数值,闭包中封闭或绑定了在另一个作用域或上下文中定义的变量。这里说闭包是一种特殊的函数值。 维基百科中的说法是:在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的... 阅读全文
posted @ 2016-08-07 12:40 robin·张 阅读(638) 评论(0) 推荐(0) 编辑
摘要: 调用函数可以说成是将函数应用于实参。如果传入所有的预期的参数,就完全应用了这个函数。如果只传入几个参数,就会得到一个偏应用函数。 偏应用函数是一个特殊的概念,在scala中它是使用val定义的,但是在使用时它却更像是一个函数。偏应用函数的定义更接近于python中有默认值的函数(scala实在是和python有太多相似的地方了)。 先来看一个例子: import java.util.Date d... 阅读全文
posted @ 2016-07-30 22:21 robin·张 阅读(482) 评论(0) 推荐(0) 编辑
摘要: 我们访问资源需要关注对资源的锁定、对资源的申请和释放,还有考虑可能遇到的各种异常。这些事项本身与代码的逻辑操作无关,但我们不能遗漏。也就是说进入方法时获取资源,退出方法时释放资源。这种处理就进入了Execute Around模式的范畴。 在scala里可以用函数值实现这种模式。下面是一个示例,使用Resource类演示了事务的开启和释放: class Resource private() { ... 阅读全文
posted @ 2016-07-30 10:40 robin·张 阅读(744) 评论(0) 推荐(1) 编辑
摘要: 在Scala里,下划线(_)可以表示函数值的参数。如果某个参数在函数里仅使用一次,就可以用下划线表示。每次在函数里用下划线,都表示随后的参数。 val arr = Array(1, 2, 3, 4, 5) println("Sum of all values in array is " + (0 /: arr) { (sum, elem) => sum + elem }) 上面的代码里使用了“/:... 阅读全文
posted @ 2016-07-29 07:05 robin·张 阅读(1264) 评论(1) 推荐(0) 编辑
摘要: 函数值对消除代码重复有很大的帮助。但是像函数值这样直接将一个函数作为另一个函数的参数却不太利于函数值本身的重用。 来看一个例子: class Equipment(val routine: Int => Int) { def simulate(input: Int) = { print("Running simulation...") routine(input) } } 在... 阅读全文
posted @ 2016-07-27 22:38 robin·张 阅读(364) 评论(0) 推荐(0) 编辑
摘要: 在线广告的核心问题就是广告的三方——广告主、媒体和广告商——之间的博弈。 具体可以参看下图: 在线广告的计算面临的主要挑战: 大规模:媒体数量很多、面向的用户极广、高并发的投放系统、严格的低延迟要求; 动态性:用户的行为和兴趣一直在变; 丰富的查询信息(主要是针对搜索广告而言) 阅读全文
posted @ 2016-07-26 22:55 robin·张 阅读(659) 评论(0) 推荐(0) 编辑
摘要: curry翻译为中文就是咖喱。意为使用curry可以让代码更有味道。 scala里的curry化可以把函数从接收多个参数转换成接收多个参数列表。也就是说我们要编写的函数不是只有一个参数列表,这个参数列表中有多个参数以逗号分隔;而是一个函数中有多个参数列表,每个参数列表中只有一个参数(当然,也可以有多个参数)。也就是说我们写的函数不再只是这样子的: def foo(a: Int, b: Int, c... 阅读全文
posted @ 2016-07-26 22:30 robin·张 阅读(1116) 评论(0) 推荐(0) 编辑
摘要: 上一节的函数值只有一个参数。函数值当然也是可以有多个参数的。看一下下面的inject方法: def inject(arr: Array[Int], initial: Int, operation: (Int, Int) => Int): Int = { var carryOver = initial arr.foreach(element => carryOver = operation(... 阅读全文
posted @ 2016-07-25 23:39 robin·张 阅读(1602) 评论(0) 推荐(0) 编辑
摘要: scala的一个最主要的特性就是支持函数编程。函数是函数编程中的一等公民:函数可以作为参数传递给其他函数,可以作为其他函数的返回值,甚至可以在其它函数中嵌套。这些高阶函数称为函数值。 举一个简单的例子:从1到某个数求和。使用Java很容易实现: int sum(int max){ int result = 0; for (int i = 0; i Int): In... 阅读全文
posted @ 2016-07-24 10:15 robin·张 阅读(429) 评论(0) 推荐(0) 编辑
摘要: java 的代码中多少有些不是很严谨的内容,比如下面的这段代码: public class Trouble { public static void main(String[] args) { Integer[] arr1 = new Integer[2]; arr1[0] = new Integer(1); Object[] arr2 = ... 阅读全文
posted @ 2016-07-22 07:45 robin·张 阅读(480) 评论(0) 推荐(0) 编辑
摘要: Demand:需求方,可以理解为广告主,广义上指的是代表广告主利益的一方; Supply:供应方,可以理解为媒体,广义上指的是代表媒体利益的公司。 上图说明了媒体变现手段: 托管给network(网站); 托管给广告交易市场(ad exchange); 托管给SSP(Supply Side Platform)。 通常前两种方式是同时存在的。通过实时竞价的方式对接到DSP(Demand ... 阅读全文
posted @ 2016-07-19 22:11 robin·张 阅读(376) 评论(0) 推荐(0) 编辑
摘要: 在线广告的特色: 技术和计算导向; 可以进行准确的衡量(点击率未必是准确的衡量标准,所以出现了效果广告); 技术投放和精准定向促进了广告的标准化; “媒体”概念的差异化(如门户网站、淘宝(靠近转化端)、搜索引擎、比价网站(居中))。 几个重要的行业协会: 阅读全文
posted @ 2016-07-17 22:13 robin·张 阅读(246) 评论(0) 推荐(0) 编辑
摘要: 在Java中是可以使用变长参数的,如下面的方法: public void check(String ... args){ for(String tmp : args){ System.out.println(tmp); } } 在scala中也可以使用变长参数。和java一样,也是只有最后一个参数可以接收可变长度的参数。使用方式是在... 阅读全文
posted @ 2016-07-16 23:00 robin·张 阅读(3073) 评论(0) 推荐(0) 编辑
摘要: 广告与营销的区别可以参考下图: 广告要reach的用户是潜在用户;营销的目标用户是对自己产品有明确需求的用户。 常见的渠道有硬广、SEM(搜索引擎推广)、导航网站、淘宝直通车、返利网等。 单纯比较不同渠道的ROI(收入回报的比例)意义不大,因为不同渠道在用户购买环节上所处的地位有着本质的区别。越接近demond(需求)的渠道ROI通常会越高,但是接近Supply(供应)的渠道负责的是reach潜... 阅读全文
posted @ 2016-07-16 21:59 robin·张 阅读(604) 评论(0) 推荐(0) 编辑
摘要: 这张图是一张对于广告过程的解读: 1曝光是广告的天然属性。在第一位决定了广告的效果。 广告策略的结果: 参考文档: http://blog.csdn.net/northstar087/article/details/8365008 http://www.lxway.com/404485181.htm 阅读全文
posted @ 2016-07-15 22:26 robin·张 阅读(566) 评论(0) 推荐(0) 编辑
摘要: 广告的主体:出资人(sponsor)即广告主(advertiser)、媒介(media)和受众(audience)。 广告的基础功能:借助于某种有广泛受众的媒介的力量,以较低的成本完成用户接触(reach)。 注意:完成接触后是否实现交易或其他转化不是必要条件。 广告有两大类 品牌广告:创造独特良好的品牌或产品形象,目的是提升长期的离线转化率。 效果广告:在短期内明确用户转化行为诉... 阅读全文
posted @ 2016-07-14 22:22 robin·张 阅读(337) 评论(0) 推荐(0) 编辑
摘要: 除了推演变量的类型,scala也会推演方法的返回类型。不过这里有一处需要注意:方法返回类型的推演依赖于方法的定义方式。如果用等号“=”定义方法,scala就会推演方法返回类型;否则,它就认为方法的返回为void。看一个例子: def printMethodInfo(methodName: String) { println("The return type of " + methodName ... 阅读全文
posted @ 2016-06-25 23:52 robin·张 阅读(2829) 评论(0) 推荐(0) 编辑
摘要: 看到Option类型就知道这本教材应该要说那个了。 使用过guava后,应该知道guava中的Optional类的作用是什么。算了找下原始文档好了: Optional is a way of replacing a nullable T reference with a non-null value. An Optional may either contain a non-null T ref... 阅读全文
posted @ 2016-06-23 22:34 robin·张 阅读(506) 评论(0) 推荐(0) 编辑
摘要: Any 前面已经有两次提到过:在scala中,Any类是所有类的超类。 Any有两个子类:AnyVal和AnyRef。对应Java直接类型的scala封装类,如Int、Double等,AnyVal是它们的基类;对应引用类型,AnyRef是它们的基类。 scala中,所有类的关系可以用下面这张图大致描述下: Any是一个抽象类,它有如下方法:!=()、==()、asInstanceOf()、equ... 阅读全文
posted @ 2016-06-23 21:58 robin·张 阅读(6048) 评论(0) 推荐(1) 编辑
摘要: 关于scala的类型推断前面已经提到过多次。再来看一下下面这个例子: import java.util._ var list1: List[Int] = new ArrayList[Int] var list2 = new ArrayList[Int] list2 add 1 list2 add 2 var total = 0 for (index <- 0 until list2.size()... 阅读全文
posted @ 2016-06-21 22:51 robin·张 阅读(1331) 评论(0) 推荐(0) 编辑
摘要: 前面两节学了scala的对象和伴生对象,这两个在使用的时候很有些java的静态成员的意思。 scala中没有静态字段和静态方法。静态成员会破坏scala所支持的完整的面向对象模型。不过可以通过伴生对象实现对scala的类一级的操作。 回过头来再看一遍那个Marker的例子,略做了一些调整: class Marker private(val color: String) { println("C... 阅读全文
posted @ 2016-06-20 22:35 robin·张 阅读(9054) 评论(0) 推荐(0) 编辑
摘要: 上一节中的单例对象MarkerFactory 就是一个独立对象的例子。尽管它管理着Marker类,但是它并没有关联到任何类上。 scala也可以创建关联到类上的对象。这样的对象同类共享同一个名字,这样的对象称为伴生对象,对应的类就称为伴生类。在scala里,类和伴生对象没有界限,它们互相可以访问彼此的private 方法和private 属性。下面使用伴生对象重写了Marker: class Ma... 阅读全文
posted @ 2016-06-19 22:46 robin·张 阅读(773) 评论(0) 推荐(0) 编辑
摘要: java中的单例模式都很熟悉了:简单地说就是一个类只能有一个实例。在scala中创建单例对象非常简单,创建类时使用object关键字替换class即可。因为单例类无法初始化,所以不能向它的主构造函数传递参数。 下面是一个单例的示例: class Marker(val color: String) { println("Creating " + this) override def to... 阅读全文
posted @ 2016-06-17 22:51 robin·张 阅读(2205) 评论(0) 推荐(0) 编辑
摘要: 在scala里,类继承有两点限制: 重写方法需要使用override关键字; 只有主构造函数才能往父类构造函数中传参数。 在java1.5中引入了override注解,但不强制使用。不过在scala中要想重写方法必须使用override关键字。如果确实重写了父类的方法又不使用override关键字的话,则会在编译时报错,提示没有使用override修饰符。 scala的副构造函数必须调用主构造函... 阅读全文
posted @ 2016-06-16 22:29 robin·张 阅读(1594) 评论(0) 推荐(0) 编辑
摘要: 在上一节创建了一个scala类,如果没有更多的方法,scala类的定义还可以更简单一些,看一下下面这个CreditCard类的定义: class CreditCard(val number: Int, var creditLimit: Int) 是的,只用一行就完成了类的定义,连大括号都不需要。 因为scala也是运行在JVM上,可以考虑以java的方式来看看编译后的类文件。查看的方式还是比较灵活... 阅读全文
posted @ 2016-06-15 22:36 robin·张 阅读(2752) 评论(0) 推荐(0) 编辑
摘要: 这里会通过与Java比较的方式来说明scala是如何创建类的。 先来看一下Java中是如何定义一个类的: public class Car { private final int year; private int miles; public Car(int yearOfMake) { year = yearOfMake; } ... 阅读全文
posted @ 2016-06-13 22:53 robin·张 阅读(684) 评论(0) 推荐(0) 编辑
摘要: scala的访问修饰符有如下几个特性: 如果不指定访问修饰符,scala默认为public; 较之Java,scala对protected的定义更加严格; scala可以对可见性进行细粒度的控制。 scala的默认访问修饰符 如果没有修饰符,scala会默认把类、字段、方法的访问修饰符当做public。如果要将之调整为private或protected,只需在前面添加对应的修饰符关键字即可。... 阅读全文
posted @ 2016-06-13 22:28 robin·张 阅读(1547) 评论(0) 推荐(0) 编辑
摘要: = 赋值运算 scala的赋值运算和java的有着很大的不同。如a=b这样的赋值运算,在Java中返回值是a的值,在scala中返回的则是Unit(Unit是值类型,全局只存在唯一的值,即(),通常Unit只用来声明函数或方法的返回值,其他场景基本是没有意义的)。这样就很容易导致一些错误地使用,比如a=b=c这样的赋值运算在java中是绝对可以的,但是在scala中运行就会报错。看一段代码: va... 阅读全文
posted @ 2016-06-11 23:07 robin·张 阅读(423) 评论(0) 推荐(0) 编辑
摘要: scala有一些默认做法,会让代码更简洁、更易读写,下面列出了这样几个特性: 1. 支持脚本。scala支持脚本,因此无须将所有的代码都放到类里。如果脚本可以满足需求,就将代码放到一个脚本里,无须再创建一个冗余的类。 2. return是可选的。如果没有写return关键字,方法调用会自动返回最后一个求值的表达式——如果它符合方法声明的返回值类型。 3. 分号“;”是可选的。不必在每个语句的后面都... 阅读全文
posted @ 2016-06-08 22:55 robin·张 阅读(893) 评论(0) 推荐(0) 编辑
摘要: 从语法上来说scala是没有运算符的。之前的一节里也曾提到过scala的运算符实际上是方法名,如1 + 2实际上就是1.+(2)。我们可以将之视为运算符,是因为scala的一个特性:如果方法的参数小于等于1个的话,那么“.”和括号就都是可选的。 scala的运算符重载指的就是重载+、-这样的符号——和C、java或者python等语言不一样,我们需要自己定义这些符号如何实现。 下面看一个“+”运算... 阅读全文
posted @ 2016-06-07 22:58 robin·张 阅读(1794) 评论(0) 推荐(0) 编辑
摘要: scala中的字符串类就是java中的java.lang.String类。不过scala也为String提供了一个富封装类:scala.runtime.RichString。 scala可以将java.lang.String类自动转换为scala.runtime.RichString类。这样就可以非常方便地使用capitalize()、lines()和reverse()等方法相对较便捷的方法(有时... 阅读全文
posted @ 2016-06-05 22:42 robin·张 阅读(5680) 评论(0) 推荐(0) 编辑
摘要: 假定要在一个方法中返回多个值。比如需要返回一个人的名、姓和邮箱地址。在Java中最常用的方法是定义一个Person类,其中包括相对应的字段;还有些不常用的方法就是返回一个集合或数组,拿到结果后再进行循环取值。在Scala中我们又多一个选择:元组。 元组是一个不可变的对象序列,可以使用逗号分隔的值进行创建,比如这个有3个对象的元组:(“robin”, “zhang”, “robin@zhyea.co... 阅读全文
posted @ 2016-06-04 23:33 robin·张 阅读(3699) 评论(0) 推荐(1) 编辑
摘要: 在Java中变量类型分为两大类:基本类型和引用类型。虽然在JDK1.5以后引入了自动装箱和自动拆箱机制,大大减少了我们在直接类型和引用类型之间的纠结,但仍有一些我们不得不考虑的问题。比如我在工作遇到的基本类型和其包装类型的默认值的问题,比如泛型只能使用引用类型,比如默认情况下直接类型的值不能作为对象来操作(1.toString()就不能通过编译)等等。 在scala中一切都是对象。 在scala中... 阅读全文
posted @ 2016-06-01 23:15 robin·张 阅读(998) 评论(0) 推荐(0) 编辑