基本函式式短碼
這裡會有一些基本的函式式短碼的例子
Java趣味短碼
Java趣味短碼 - (第一節)
今天跟公司的童鞋聊天的時候,談到了關於短碼和程式碼的精簡的方式,所以整理出來。
需求很簡單。
首先定義一個類
class Item{
public int key;
public int l;
public int r;
};
然後主函式的場景大概是這樣
public static void main(String[] args) {
Item x;
x = new Item();
x.key = 1;
x.l = 10;
x.r = 20;
int i = 0;
if (x.key > i){
i = x.l;
}else{
i = x.r;
}
i = 0;
if ( x.key > i){
x.l = i;
}else{
x.r = i;
}
}
這裡面有兩個子場景,就是接下來要討論的。
子場景1
if (x.key > i){
i = x.l;
}else{
i = x.r;
}
子場景2
if ( x.key > i){
x.l = i;
}else{
x.r = i;
}
子場景1 的規律是 左面的值都是一樣的,都是賦值給i
子場景2 的規律是 右面的值都是一樣的,都是用i賦給別的變數。
那麼我們如何來簡化實現這兩類場景呢?
第一個場景很簡單,可以如下優化:
i = ( x.key >i ? x.l : x.r);
第二個場景比較棘手!
因為表示式不能被賦值。
所以我們增加一個函式:
public static boolean to_(Object s ){
return true;
}
有了如上函式我們就可以這樣寫
( x.key >i ? to_( x.l = i ): to_(x.r = i) )
這裡的含義就是先複製給x.l或者x.r根據x.key>i的真假值。然後傳給to_函式,至於to_不會考慮傳過來的值是多少。反正x.key>i都會判斷。直接暴力返回true。這樣就完美的解決了左賦值的問題。也解決了Integer和int無法passbyValue的問題。
如下是完整的程式碼。
package tPackge;
class Item{
public Integer key;
public Integer l;
public Integer r;
};
public class test01 {
public static boolean to_(Object s ){
return true;
}
/**
* @param args
*/
public static void main(String[] args) {
Item x;
x = new Item();
x.key = 1;
x.l = 10;
x.r = 20;
Integer i = 0;
if (x.key > i){
i = x.l;
}else{
i = x.r;
}
System.out.println(x.l);
System.out.println(x.r);
System.out.println(i);
System.out.println("--------------------------");
i = ( x.key >i ? x.l : x.r);
System.out.println(x.l);
System.out.println(x.r);
System.out.println(i);
/*
if ( x.key > i){
x.l = i;
}else{
x.r = i;
}
*/
System.out.println("--------------------------");
i = 0;
//if ( x.key > i ) { x.l = i; } else { x.r = i; }
//if ( ( x.key >i ? ( ( x.l = i ) == i ): ( (x.r = i) == i ) ) ){ System.out.println(i); }
if ( ( x.key >i ? to_( x.l = i ): to_ (x.r = i) ) ){ System.out.println(i); }
System.out.println(x.l);
System.out.println(x.r);
}
}
Java趣味短碼 - 能像 python的 enumerate一樣嗎?
Java趣味短碼 - 能像 python的 enumerate一樣嗎?
昨天和童鞋討論過關於IF,然後童鞋的朋友是個pythoner,也在一起討論,當時提出一個問題,java沒有像python裡的enumerate這個東西吧?其實java裡沒有的東西還慢多的。不過我們可以讓他有。
下面是python的程式碼
for index,var in enumerate(a):
tl = tl + [ var-n+index , var , var+n-index ]
enumerate(a)
假設
a = ["test","hello","test"]
能根據a的結構生成如下結構:
a = (0,"test"),(1,"hello"),(2,"test")
在java中如何實現呢?
如果你去搜尋stackoverflow 找到這樣一篇文章,戳進
裡面的方法是這樣
List<String> numbers = Arrays.asList("zero", "one", "two");
ListIterator<String> it = numbers.listIterator();
while (it.hasNext()) {
System.out.println(it.nextIndex() + " " + it.next());
}
如上的方法雖然實現了基本需求,但不美觀。
那麼我們怎麼實現呢?
思路如下:
- 實現迭代器
- 建立一個替代物件,增加一個索引和一個物件。
首先定義一個迭代物件
@SuppressWarnings("unused")
class Enum{
public int I;
public Object Obj;
public Enum( Object Obj , Integer I){
this.I = I;
this.Obj = Obj;
}
}
然後我們定義enumerate物件
@SuppressWarnings("unchecked")
class Enumerate<T> implements Iterator<Enum> , Iterable<Enum>{
private Iterator it ;
private int current;
public Enumerate(Collection<T> t){
it = t.iterator();
}
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public Enum next() {
return new Enum(it.next(),++current);
}
@Override
public void remove() {
it.remove();
}
@Override
public Iterator<Enum> iterator() {
return this;
}
}
這個物件我們增加了一個current計數器。用來返回index的
這裡要說明為什麼不用stackoverflow帖子中的方法,缺點就是當list或者set這種集合過大的時候。那麼你的演算法週期就要*2。這是很難讓人接受的事情。
所以使用迭代的話,會逐條記錄返回,這樣不會改變原來的程式碼時間。
SO!我們可以看到如下程式碼了。
for ( Enum a : new Enumerate<Integer>(l)){
System.out.println(a.Obj);
System.out.println(a.I);
}
是不是感覺很酷!
下面的程式碼是一份完整的程式碼樣例。
package tPackge;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
@SuppressWarnings("unused")
class Enum{
public int I;
public Object Obj;
public Enum( Object Obj , Integer I){
this.I = I;
this.Obj = Obj;
}
}
@SuppressWarnings("unchecked")
class Enumerate<T> implements Iterator<Enum> , Iterable<Enum>{
private Iterator it ;
private int current;
public Enumerate(Collection<T> t){
it = t.iterator();
}
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public Enum next() {
return new Enum(it.next(),++current);
}
@Override
public void remove() {
it.remove();
}
@Override
public Iterator<Enum> iterator() {
return this;
}
}
public class test02 {
/**
* @param args
*/
public static void main(String[] args) {
List <Integer> l = Arrays.asList(1,2,3,4,5,5);
int i = 0;
for ( Integer a : l){
System.out.println(i);
System.out.println(a);
i++;
}
for ( Enum a : new Enumerate<Integer>(l)){
System.out.println(a.Obj);
System.out.println(a.I);
}
}
}
java趣味短碼-for的邏輯操作對比
java趣味短碼-for的邏輯操作對比
前面介紹了三元表示式和三元表示式的用法,當然還有迭代器。下面就是一個比較特殊的問題,for的寫法長度比較和優劣。當然這也是一個和童鞋討論思考了很久的問題。
首先說明一下里面的做法參考的stackoverflow中的一篇討論貼子中的關於each的做法。
首先我們準備一下相關函式
建立一個介面,用來實現each操作用的
interface Function<T>{
public void func(T Item);
}
實現一個each函式。
@SuppressWarnings("unchecked")
public static <T> void each(Collection<T> s, Function f){
for ( T a : s){
f.func(a);
}
}
實現一個集合增加元素的三元表示式邏輯操作函式。
public static <T> int add_(Collection<T> s, T item){
s.add(item);
return 0;
}
我們的需求如下:
需求1:在指定的List中去掉小於等於2的元素,大於2的元素放到目標列表d中,並列印d中所有的元素,我們只針對過濾元素的程式部分進行優化。
List <Integer> l = Arrays.asList(1,2,3,4,5,6,7);
final List <Integer> d = new ArrayList<Integer>();
for ( Integer a : l){
if (a > 2){ d.add(a); }
}
我們需要優化的程式碼如下:
for ( Integer a : l){
if (a > 2){ d.add(a); }
}
下面我們看看,有2種寫法:
//first
test03.each(l, new Function<Integer>(){
@Override
public void func(Integer Item) { if ( Item > 2) { d.add(Item); } }
});
優點:去掉了for,把他封裝到了函式裡,更專注元素的處理,且邏輯更鮮明,程式碼行數的可預料性大。
缺點:可擴充套件的難度十分大,比如需要2個元素對比等,需要開發不同的需求的each版本,不過實際上這個缺點也算是優點,因為會使程式碼規範化,程式更能公式化。
for ( Integer a : l ){ int b = ( a >2 ? add_(d,a) : 0 ) ; }
優點:僅僅從程式碼行數和程式碼文字列數來說,這樣寫確實精簡了。
缺點:幾乎不適合作為client-code的典範,不推薦這樣寫。
總結: 從上面看,如果剛開始就需要對程式碼進行統計和規範化建議first寫法,並且可以開發出來一套這樣的函式式框架提供給程式設計師,程式碼的統計和程式碼的規範化更易於預測和思考(因為基本都可以通過公式化的開銷來計算)
需求2:在指定的List中 小於等於2的元素增加1並存放在目標列表中,大於2的元素直接放到目標列表中。
原始碼如下:
for ( Integer a : l){ if (a > 2){ d.add(a); } else { d.add( a + 1); } }
寫法 1
//first
test03.each(l, new Function<Integer>(){
@Override
public void func(Integer I) {
if ( I > 2) { d.add(I); } else { d.add(I+1); }
}
});
優點:同上。
缺點:同上。
補充 : 這時候已經能夠凸顯固定模式
的函數語言程式設計
的特點了。
寫法2
//second
for ( Integer a : l ){ int b=( a >2 ? add_(d,a) : add_(d,a+1) ); }
優點:比標準寫法短了不少!。
缺點:對更多的if elseif else這樣的結構,這種寫法直接就被pass了,所以經證明這種寫法在if else這樣的條件結構的時候,還蠻不錯。
總結:
需求1,不優化是最簡潔的,但第1種優化的擴充套件和模式化程式設計較好。
需求2,第2種優化最短,可讀性也不錯,但擴充套件性為0
結論:第一種優化確實不錯的,在Java中android平臺被這種寫法是被廣泛應用。
相關文章
- 短函式有感函式
- EXCEL 基本函式Excel函式
- TAPI基本函式 (轉)API函式
- 機器學習基本函式介紹機器學習函式
- fork()函式的基本用法函式
- VC基本函式一覽函式
- python函式的基本使用Python函式
- string 函式的基本用法函式
- Javascript函式的基本知識JavaScript函式
- 圖解 ReactiveCocoa 基本函式圖解React函式
- 數學函式庫(基本版)函式
- 7 個基本的 JS 函式JS函式
- Oracle 的基本函式介紹Oracle函式
- pytorch tensor的基本函式PyTorch函式
- MATLAB常用基本數學函式Matlab函式
- 分割槽函式Partition By的基本用法函式
- 【函式式 Swift】函式式思想函式Swift
- MySQL函式大全(字串函式,數學函式,日期函式,系統級函式,聚合函式)MySql函式字串
- 生成密碼函式密碼函式
- Oracle 函式大全(字串函式,數學函式,日期函式,邏輯運算函式,其他函式)Oracle函式字串
- jQuery函式的等價原生函式程式碼示例jQuery函式
- Hive的基本介紹以及常用函式Hive函式
- ROW_NUMBER() OVER函式的基本用法函式
- getopt_long函式基本用法-linux函式Linux
- Matlab影像處理常用基本函式Matlab函式
- mysql儲存過程基本函式(轉)MySql儲存過程函式
- python中id()函式、zip()函式、map()函式、lamda函式Python函式
- 【函式】Oracle函式系列(2)--數學函式及日期函式函式Oracle
- (譯) 函式式 JS #2: 函式!函式JS
- Python 擴充之特殊函式(lambda 函式,map 函式,filter 函式,reduce 函式)Python函式Filter
- 第7章 IF函式 COUNTIF函式 SUMIF函式函式
- 字元函式、數字函式和日期函式字元函式
- 【函式】Oracle EXTRACT()函式與to_char() 函式函式Oracle
- MySQL(四)日期函式 NULL函式 字串函式MySql函式Null字串
- 核函式 多項式核函式 高斯核函式(常用)函式
- C++(STL原始碼):37---仿函式(函式物件)原始碼剖析C++原始碼函式物件
- java的基本函式(介紹)--過載概念、基本應用Java函式
- 【函式】ORACLE函式大全函式Oracle