Java NIO2(AIO) 进行文件异步读取

在  NodeJS 中进行异步操作很简单,而 Java 到了  7 开始才支持异步的 IO 操作。虽然之前的版本有引入非阻塞 IO,但编码中还不易体现出它的优越性。亮一下 NodeJS 用异步 IO 的例子:

var fs = require('fs');
fs.readFile('Test.scala', 'utf-8', function(err, data){
  if( !err ) {
    console.log(data);
  }
});

console.log('continue doing other thins');

执行输出是

continue doing other things
CONTENT FROM FILE Test.scala

对的,理想中的异步操作就是,传递回调函数来读取文件,读取完成后招待回调,且不阻塞主线程。

在 Java 8 之前,因为没有 Lambda 支持只能应用内部类的方式。JDK 提供了以下异步 Channel 来实现异步操作

AsynchronousFileChannel 阅读全文 >>

三种方式告知泛型类或泛型方法具体类型

在上一篇中写道 Java 泛型 -- 依据声明的变量类型自动推断,主要是说明了通过声明类型告知泛型方法具体类型,其后有个小结三种方式告知泛型类或泛型方法具体类型,在此重列如下:

一. 具体类型写在两尖括号中

1. List<String> list
2. new HashMap<String, String>
3. instance.<String>foo()   //如方法 <T> T foo() { return (T) obj; }

二. 变量声明类型指示具体类型

1. List<String> list = new ArrayList<>()   // 这个例子应该可以列在这里,List<String> 指示了具体类型是 String, 所以后只需要空 <>,JDK7 or later
2. String s = obj.foo()   //比如方法是 <T> T foo() { return (T) obj; }, 由于前面的 String s 声明,所以不必写成 String s = instance.<String>foo()

三. 实参类型指示具体类型

1. instance.foo(String.class)  //方法为 <T> T foo(Class<T> type) { return (T) obj; }, instance.foo(String.class) 返回的就是字符串值
2. instance.foo("abc")  //方法为 <T> foo(T value) { return (T) obj; }, instance.foo("abc") 返回的就是字符串值 阅读全文 >>

Java 泛型 -- 依据声明的变量类型自动推断

Java 泛型在调用方法操作时应用具体参数还是很好理解的,比如

Map<String, Integer> map = new HashMap<>();  //钻石操作符是 JDK 1.7 引入的

后续的 put 操作调用的具体方法就是

Integer put(String key, Integer value)

因为  put 方法的原型是

V put(K key, V value)

上面的代码我们是看到了 <>,所以知道是泛型调用。有时候并不需要 <>,但实际上也是进行的泛型调用,那就是 Java  可以依据变量声明类型来作特化调用 -- 应用具体参数类型。

例如:

List<String> list = Collections.emptyList();  //虽不见 <>, 但同样是泛型调用,类型为 String 阅读全文 >>

Vi 中的光标位置操作

Vi 中的光标操作是其他众多命令,如(d-delete, c-change, yy) 的基础。它犹如汇编中的寄存器/寻址方式,成为了许多 Vi 的初学者望而却步的一主要原因,特别是在某些系统版本的 Vi 中无法正常使用方向键移动光标的情况。那么好的习惯还是请试着用 h, j, k, l 来当方向键,对于键盘控来说,把手从字母上移动到方向键上去都是在浪费时间。

本来是想直接记录一下在 Vi 中怎么进行删除、修改操作的,然而却发现 Vi 的光标操作是无法逾越的一道沟。在这里,我会试着去理解每一个按键的更自然的意义,现在开始拉清单 阅读全文 >>

Vim 中使用被选择文本以 Shell 命令执行

在 Vi 中如果想选取文本作为 Shell 命令来执行该如何做呢? 想法的背景是想在 Vi 中编辑 Shell 命令,主要是对参数的修改,然后直接选择执行,而不希望复制再贴到 Terminal 下看结果。方法其实很简单,用不着使用 VimShell,关键这个插件的安装还依赖于另两个插件。方法就是:

1. 可视模式选择文本,选择技巧, 按 v 逐字选择,j 从光标位置到行尾,最有用的莫过于大 V,以行为单位选择,所以按一下大 V 直接选中当前行
2. Shift+; 进到 :'<,'> 提示符
3. 输入 w !sh, 回车即可,要用 fish 就用  w !fish

效果

vi-selection-shell

原理(这个表述其实不怎么准确):其实进行的是一个管道操作,把选择的文本内容输送给 sh 执行,相当于

echo "echo 'Hello world'" | sh

如果想把执行结果输出到文件或是剪贴板, 就可借题发挥下了,比如 阅读全文 >>

Vi 使用 Vundle 管理插件执行 PluginInstall 出错

Vi 有了 Vundle 这么一个总管(插件管理器),安装插件着实太省事了,再也不需要自己把 *.vim 文件放在各处。只需要做一次

$ git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim

编辑好 ~/.vimrc 文件,装什么每次在这个文件中加上 Plugin 'scrooloose/nerdtree',运行 :PluginInstall 即可。

我第一次体验执行 vim +PluginInstall +qall (和在 Vi 中执行 :PluginInstall 同一效果), 总是得到类似这样的错误

Error detected while processing function vundle#installer#new..<SNR>46_process..vundle#installer#run..vundle#installe
r#install..<SNR>46_sync..<SNR>46_make_sync_command..<SNR>46_get_current_origin_url..<SNR>46_system:
line    1:
E484: Can't open file /var/folders/xz/vqv039517flcxtqzrq_jjy1xqzfzc0/T/v0rQ2fl/1
Error detected while processing function vundle#installer#new..<SNR>46_process..vundle#installer#run..vundle#installe
r#install..<SNR>46_sync: 阅读全文 >>

Vi 寄存器操作,及使用系统剪贴板

使用 Vi 不得不提它强大的寄存器功能,一般操作系统只支持单例的剪贴板操作,而 Vi 借助于寄存器,相当于有几十个剪贴板可以使用。Vi 中针对内容的操作会记入到寄存器中,包括复制,粘贴,删除,以及只读的寄存器和与系统剪贴板交换内容的寄存器。本文最初目的是怎么与系统剪贴板交换内容。

在 Vi 中使用 :reg (:registers 或 :dis/:display) 命令显示寄存器中的内容

vi-registers

主要寄存器

阅读全文 >>

Vi Buffer 的基本操作

在 vi 中打开过多个文件时,每个文件都是存放在各自的 buffer  中,可以用命令 ls (buffers 或 files,三个命令中拣你最喜欢的一个即可,ls 输入方便,buffers/files 更表意) 显示所有的 buffer。显示出来的结果如下:

vi-list-buffers

可以看到

每个 Buffer  的编号,分别是 1, 4, 5, 6
% 表示的是当前窗口中的 Buffer
+ 表该 Buffer  中的内容有修改
Buffer 中的文件名称 阅读全文 >>

Scala 函数式编程学习视频 -- 条件和值定义

Scala 的 if 和 Java 中的用法差不多,但它在 Scala 是个表达式而不仅是条语句,它是有返回值,这让我们用起来很方便。在 Java 中我们一般先声明一个变量,在 if 语句中不同条件下赋不同的值。Scala 中就一条赋值表达式

val a = if (x == 5) 100 else if(x == 10) 200 else 300

val 关键字是用来定义值的,value 的缩写,就是 Java 中的常量 public static final

这里也同样涉及到了 call-by-name, call-by-value,到 Scala 控制台下试下

scala> val a = (1 to 1000000000).foldLeft(0){(a,b)=>a+b} //定义时就要算出 foldLeft 的值,所以需要耗费些时间
a: Int = -243309312

scala> def b = (1 to 1000000000).foldLeft(0){(a,b)=>a+b} //定义时很快,每次使用 b 时计算,其实就是定义一个方法,应该好理解
b: Int

阅读全文 >>