java style_Java-Style

点击这里或这里获取中文文档

#Style

Bring efficient coding style from other languages to JAVA 8.

Style is a library that simulates programming in other languages with carefully choosen method/class names.

Style focuses on making your code prettier, less reinventing--wheels and well-understood.

Referenced languages : Scala, PHP, JavaScript, Groovy, C++, and C#.

Maven

net.cassite

style

2.0.1

#Why Style?

Style is a free, light-weight, and open-source project with detailed tutorial.

I am using Style everywhere since I built it.

#Preview

// define a function to see if list contain a person with given name:

def check = $(

(List ls, String name) -> null != $(list).forEach(e -> {

if (e.name().equals(name))

return true;

return null;

}));

check.apply(list, "cass");

// If expression with return value:

System.out.println(If(

$(list).findOne(e -> e.name().equals("cass")),

res -> {

return res.id();

}).Else(() -> "Not Found!"));

// forEach with iterator info

$(list).forEach((e, i) -> System.out.println(

"Element is:" + e + " Index is:" + $(i)));

// dozens of new features waiting for you to explore.

Fell free to contact me through wkgcass@hotmail.com.

And pls execuse me for my poor english...

#Update

2.0.1 --> 2.0.2

Utils module adds File support ,allow you to operate on files using UNIX style.

#Directory

Starting

Functions

Supporting Interfaces

Define

Call

Async, Await and Exception Handling

Callback

Language

Basic

Exceptions

Type Conversion

Pointers

Tuple

Mutable Boxed Types

Reflection

Class

Constructor

Field

Method

Dynamic Proxy

Read-Only objects

Thread

callback

(async)

original thread simplify

Logic

If

Switch

For

For-to-step

While

Control

Break

BreakWithResult

breakable

Continue

Remove

(List-Only)

Set

Add

Iteration

Constructing

forEach/forThose

to-via Collection Transform

find

Other

Avoid Null

Date

RegEx

Comparable

Rand

String

JSON

join

File

PathMapper

Appendix

last loop result

#Starting

import net.cassite.style.jar

Create a Class, and then import static net.cassite.style.Style;

e.g.

import static net.cassite.style.Style.*;

class YourClass {}

If you need other modules, here's what you might need.

import static net.cassite.style.Style.*;

import static net.cassite.style.Aggregation.*;

import static net.cassite.style.Utils.*;

import static net.cassite.style.Reflect.*;

or, you can use coding like this:

Aggregation.$(list).findOne(e->...);

#Functions

##Supporting Interfaces

Interfaces look like this:

@FunctionalInterface

public interface RFunc2 {

R apply(T0 arg0, T1 arg1) throws Throwable;

}

8 interfaces with return value and 8 interfaces without return value are built in, you can see them in net.cassite.style.interfaces.

##Define

The definition is similar to Scala or JavaScript

def funcName=$(Interface);

// or

def funcName=function(Interface);

e.g.

def check = $(

(List ls, String name) -> null != $(list).forEach(e -> {

if (e.name().equals(name))

return true;

return null;

}));

##Call

Use apply to call a function on caller's thread.

e.g.

check.apply(list, "cass");

Functions can receive more or less values than its argument length.

e.g.

check.apply(list, "cass", "arg");

// "arg" will be ignored

check.apply(list)

// same as 'check.apply(list, null)'

Use applyCheckPrimitive to avoid null values when result is auto-unboxed.

e.g.

def predicate = function(...);

boolean b = predicate.applyCheckPrimitive(boolean.class, arg);

##Async, Await and Exception Handling

Async, Await is a great multi-thread model. With Style you can use async/await with no extra code.

Use async to async-call a function, a Async object would be returned. You can retrieve value using .await()

e.g.

Async async = check.async(list, "cass");

Boolean res = async.await(); // retrieve value;

// or

res = await(async);

When calling await, the curren thread would pause until async mission finished or thrown with an exception.

To handle exception from async, you can set a listener function to Async object.

e.g.

async.onError((err) -> err.origin().printStackTrace());

Type of 'err' is StyleRuntimeException, all exceptions from async-call would be packed with StyleRuntimeException.

The handling process would invoke immediately if async-process finished or thrown with an exception when calling onError.

Or it will wait until process finishes or throws with exceptions, and deal with err on Async Thread.

If you want to handle the exception on caller's thread, you can invoke awaitError instead

e.g.

async.awaitError((err)->...);

It would block the thread until async process finished or thrown with an exception.

###Callback

Call back is used everywhere in JavaScript

It's very easy to use callback method to deal with multi-thread programming.

Method async means you can call a function on another thread, so put a callback function into async-function arguments and invoke it inside the async-function would achieve calling-back.

#Language

##Basic

###Exceptions

Style provides an easy way of handling exceptions with StyleRuntimeException.

Usually we throw an exception in this way:

throw new RuntimeException(e);

With Style, you can

throw $(e);

then, a StyleRuntimeException would be thrown.

If (e instance of StyleRuntimeException), the $(e) would simply return object e without packing.

StyleRuntimeException provides method origin() to get packed Throwable object.

And it @Override getCause() method,

return super.getCause().getCause();

###Type Conversion

Type conversion can take many lines and mix with other logics.

Style helps you convert types easily.

To use type conversion,

the class to convert to may contain methods like:

public TO_TYPE static from(FROM_TYPE obj){...}

Or the class of the object to convert may contain methods like:

public TO_TPYE toTO_TYPE(){...}

e.g.

The following definition means you can convert String to User or convert User to String.

class User{

static User from(String s)...

String toString()...

}

Invoke T imp(Object, Class) to finish the conversion.

It separeates converting process from real logics, and make your code prettier.

###Pointers

Java don't have pointers for us to use. But with a object packing another object, here's our pointer.

ptr p=ptr(T t);

$(p) // get value from the pointer, like *p in C++

$(p, T newValue) // set value of the pointer, like *p=newValue in C++

Also, you can access the packed object using :

p.item

Pointers may be helpful when dealing with non-final variables using anoymous classes.

If the given object has interface(s), a proxy object would automatically be generated.

Use

p.proxy

to access the proxy object.

p.proxy simply invokes methods on p.item, which looks exactly like what a pointer would do in C/C++.

###Tuple

Tuples are offered since 1.1.3.

They are scala-style tuples, but with some convenient methods to use when needed.

Use fields like tuple._1 / tuple._2 to get elements.

Use *tuple(e1, e2, ...) to create tuples

There are 7 built in tuples

Tuple1, Tuple2, ... , Tuple7, all of them offer _index when accessing elements. (index starts at 1)

They all implement interface Tuple

interface Tuple{

T $(int index); // retrieve element, starting with 1

int count(); // amount of elements in the tuple

}

You can use $(index) to get same element as _index

and use count() as the end of an iteration.

e.g.

for(int i=1;i<=tuple.count();++i){

...

}

###Mutable Boxed Types

mutable boxed types are provided. Use Utils.$(type) to generate.

though string are in same package as other MTypes, it's not a mutable type. detailed explanations will be given in chapter Other

MInteger(mutable boxed type for int) provides to(int) and until(int), which can be used to generate consistent sequence with/without the last integer.

e.g.

$(0).to(20)

means list(0,1,2,...,20)

$(0).until(20)

means list(0,1,2,...,19)

##Reflection

Classes/Fields/Methods/Constructors are packed into a supporting object. Check packet net.cassite.style.reflect for more info.

###Class

We used to write this:

obj.getClass();

TYPE_NAME.class;

Class.forName(className);

Now, you can retrieve a class supporting object using

ClassSup> cls = cls(obj);

ClassSup cls = cls(TYPE.class);

ClassSup> cls = cls(className);

ClassSup let you easily get Generic Supported constructors', fields', and methods' supporting objects.

// no args

ConstructorSup con = cls.constructor();

// with args

ConstructorSup con = cls.constructor(T0.class, T1.class, ...);

FieldSupport f = cls.field(fieldName, FIELD_TYPE.class);

// no args

MethodSupport f m = cls.method(methodName, RETURN_TYPE.class);

// with args

MethodSupport f m = cls.method(methodName, RETURN_TYPE.class, T0.class, T1.class, ...);

Also, you can get all declaired methods or fields from the class and its super classes.

List> list=cls.allFields();

List> list=cls.allMethods();

###Constructor

You can create an instance with constructor supporting object.

TYPE o = con.newInstance();

TYPE o = con.newInstance(arg0, arg1, arg2, ...);

###Field

FIELD_TYPE v = f.get((TYPE)obj);

###Method

RETURN_TYPE r = m.invoke((TYPE)obj);

RETURN_TYPE r = m.invoke((TYPE)obj, arg0, arg1, arg2, ...);

There's no need for setAccessible(true), Style has done that for you.

All these supporting classes contain methods like

isPublic()

isStatic()

isFinal()

...(9 more)

which help you check modifiers.

###Dynamic Proxy

We used to create a dynamic proxy in this way:

Proxy.newProxyInstance(

proxyTarget.getClass().getClassLoader()

, proxyTarget.getClass().getInterfaces()

,handler);

Though JDK designed it this way for better reusable programming. But usually we don't need too many features.

As a result, it contains many repeating codes. Style helps you simplify this operation.

T proxy(handler, proxyTarget);

Also,Style provide aother way.

Use List.get method as an example

Use anoymous class to create a ProxyHandler instance:

ProxyHandler> handler = new ProxyHandler>(list) {

@SuppressWarnings("unused")

String get(int index) {

System.out.println("before get invoked with arg0:" + index);

String res = target.get(index);

System.out.println("after get invoked with res:" + res);

return res;

}

};

ProxyHandler receive an object as the object to proxy, it's stored in a field called target.

As you can see, it uses RETURN_TYPE methodName(Args) to define an 'Around' proxy. This method looks exactly the same as the method to proxy.

generate

List listProxy = proxy(handler);

this way makes proxy more readable.

####Read-Only objects

Usually, we need to create readonly objects in case someone change them.

e.g. We may have to pack an object into another and expose it to other modules. However we cannot guarantee other people not changing it.

Style provides you an easy way of turning an object with interfaces into a read-only one.

Usually it doesn't require you doing any extra work.

R readOnly(R r);

When an invocation comes, Style will check the method.

if methodName.contains elements in $.readOnlyToSearch

Check whether the method has ReadOnly annotation

if has

do invoking

else

throw an exception(ModifyReadOnlyException)

else

Check whether the method has Writable annotation

if has

throw an exception(ModifyReadOnlyException)

else

do invoking

Note that, all exceptions are packed into StyleRuntimeException

##Thread

###callback

We have seen callback from one async object.

If more than one async tasks should be 'joined together', you can use this:

$(Async1, Async2, Async3,...)

.callback((res1,res2,res3,...)

.onError(err->...); // optional

The callback method would invoke on a new thread.

If you need to force callback process on current thread, you can invoke

.callbackSync(...)

instead.

###thread operation simplify

When we create a thread, we usually write :

Thread t=new Thread(()->{...});

t.start();

Style can simplify the process :

Thread t = run(()->{...});

The thread will start running. No need for .start()

##Logic

Style provide logic-control expression with return values.

###If

The way of using 'If' is similar to ordinary if-expression.

If(INIT, (e)->{do something...})

.ElseIf(INIT, ()->{do something...})

.Else(()->{do something...});

If INIT!=null && !INIT.equals(false)

apply the second argument

if the function has no args

apply anyway.

func.apply();

else

apply with INIT

func.apply(INIT);

else

process expressions defined in elseif and else block.

INIT can also be a lambda expression. e.g. ()->INIT or more complex expressions.

The If expression can also end with End() instead of Else(()->{})

If Expression Return Value is [applied function's return value] or given variable.

The expression to apply can also be variables. Return value would be these variables instead.

e.g.

If(3 > 4, 1)

.ElseIf(3 > 2, () -> 2)

.ElseIf(4 > 3, 5)

.Else(3);

// will return Integer.

If(1 > 2, () -> System.out.println(1))

.ElseIf(3 > 2, () -> System.out.println(2))

.Else(() -> System.out.println(3));

// void functions in if-expression will return null

###Switch

Switch(TO_SWITCH)

// or Switch(TO_SWITCH, Class) if return type is not input type

.Case(TO_TEST, ()->{...})

.Case(TO_TEST, ()->{...})

.Default(()->{...})

Switch doesn't require break.

Similar to If, functions can be replaced by variables.

e.g.

String str = Switch(6, String.class)

.Case(7, () -> "g")

.Case(6, "f")

.Default(() -> null);

###For

For(T t, t->{boolean}, t->{increment}, t->{loop});

For make last not null loop result as its return value.

if loop result is null, it won't overwrite 'last loop result'.

Maybe you want to retrieve last loop result, Style provide this kind of support, do it this way:

For(T t, t->{boolean}, t->{increment},

(t,info)->{loop}); // info contains last loop result

/*

info.currentIndex

info.effectiveIndex // how many time 'last loop result' was modified

info.lastRes // value of 'last loop result'

*/

####For-to-step

In BASIC, a for expression was provided as :

FOR i=0 TO 11 STEP 2

...

END FOR

It has the same function as :

for(int i=0; i<=11; i+=2){

...

}

Style provide this kind of for-expression. It's very useful when start and end positions are fixed.

For(NumStart).to(NumEnd).step(NumStep).loop(i->{...});

e.g.

For(1).to(21).step(2).loop((Integer i, LoopInfo info) -> {...});

// which means for(int i=1;i<=21;i+=2){...}

// info is optional

It also has return value. The behavior is the same as For.

it really help save a lot of coding. Scala uses expressions with return value.

####While

While(()->{boolean}, ()->{loop});

Similarly, you can retrieve 'last loop result' using

While(()->{boolean}, info->{loop});

The return value behavior is the same as For.

###Control

These loops cannot break in an ordinary way.

So i think it's the best way to control loops with exceptions.

####Break

Break the loop instantly

return Break(); // or simply 'Break();' if no compiling errors.

// or

throw new Break();

There's also a method breakable(()->{}) provided, which allows you breaking out of the method block. e.g.

breakable(()->{

list.stream().filter(u -> u.age > 18).forEach(u->{

if(u.name.equals("cass")) Break();

System.out.println(u);

});

});

BreakWithResult也可以使用,但不会有任何特殊作用。

####BreakWithResult

Break the loop after setting 'last loop value'.

return BreakWithResult(R res); // or BreakWithResult(R res)

// or

throw new BreakWithResult(R res);

####Continue

Jump to the next loop without writing 'last loop result'.

return Continue(); // or Continue();

// or

throw new Continue();

// or

return null;

####Remove

Invoke the current iterator's .remove() method.

Only use in $(iterator).forEach

return Remove(); // or Remove();

// or

throw new Remove();

####(List-Only)

ListIterator provide more functions. Such as Set, and Add

#####Set

Invoke ListIterator's set method.

return Set(T toSet); // or Set(T toSet)

// or

throw new $Set(T toSet);

#####Add

Invoke ListIterator's add method.

return Add(T toSet); // or Add(T toSet)

// or

throw new Add(T toSet);

#Iteration

##Constructing

It's easy for an Array to initiate with values using new T[]{...};

However collections and maps are much difficut.

Style solved the problem.

$(new ArrayList(), "hello", "world", "!");

would add 3 strings into given collection.

list("hello","world","!");

creates a new ArrayList with 3 elements in it.

$(new HashMap(),

map("a", 1).$("b", 2).$("c", 3));

would put 3 entries into given map.

map("a",1).$("b",2).$("c",3);

creates a new JSONLike(extends LinkedHashMap)

You can also add/put elements/entries into already existed collections/maps in the same way.

##forEach/forThose

JDK1.8 provide iterable objects with forEach and filter, however, they donot have return values, and they cannot be breaked out. They cannot work on an array, and they don't supply iteration info.

you can use if to achieve similar result but the code doesn't look good.

Style give Arrays, Iterables, and Maps the ability of using more advanced forEach.

Arrays, Iterables:

$(arr).forEach(e->{...});

// with iterator info

/*

info.currentIndex;

info.previousIndex;

info.nextIndex;

info.hasPrevious;

info.hasNext;

info.lastRes // result from last loop

*/

$(arr).forEach((e, info)->{...});

$(arr).forThose(e->{boolean}, e->{...});

$(arr).forThose(e->{boolean}, (e, info)->{...});

Maps:

$(map).forEach((k,v)->{...});

$(map).forEach((k,v,i)->{...}); // with iterator info

$(map).forThose((k,v)->{boolean}, (k,v)->{...});

$(map).forThose((k,v)->{boolean}, (k,v,i)->{...});

Return value have the same behavior as For

Array, Iterable, and Map support 'Break', 'Continue' and 'BreakWithResult'

Iterable and Map support control exception 'Remvoe'

List support control exception 'Set' and 'Add'

e.g.

strArr = new String[] {

"a", "b", "c", "d"

};

$(strArr).forEach(e -> {

if (e.equals("b"))

Continue();

if (e.equals("d"))

Break();

return e;

});

// the result is "c"

map = $(new HashMap()

, map("cass", 1995).$("john", 1996).$("alpha", 1994));

$(map).forEach((k, v, i) -> {

if (k.equals("alpha"))

Remove();

System.out.println("key is:" + k + " value is:" + v + " current index is:" + $(i));

});

// the result is null (because there are no return values in the loop)

// key is:cass value is:1995 current index is:0

// key is:john value is:1996 current index is:2

// it's a HashMap, the order is different from it when putting in.

##to-via Collection Transform

It's very convenient using Style transform from Arrays, Iterables, Maps to another Collection(Map also support transform to another Map).

Set set = $(list).to(new HashSet()).via(e->e+" mark");

// modify every element in list and put them into new set.

$(map).to(new HashMap()).via((k,v)->{return new Entry(k.toString(), Integer.parseInt(v));});

// change type and put into new map.

##find

Usually we need to find some elements/entries from an array, an iterable, or a map.

$(list).findOne(e->{boolean});

// return first found element, null if not found

$(list).findAll(e->{boolean});

// get all found elements and add them in a new ArrayList<>

$(list).findAll(e->{boolean}, Coll);

// get all found elements and add them in Coll

$(list).findAll(e->{boolean}, Coll, int limit);

// get all found elements and add them in Coll before Coll.size() reaches limit

Map have similar behavior, return Maps or Entries instead of Collections or Elements

findOne would return null if not found.

Also, method first is provided to retrieve the first element in the collection/map.

#Other

##Avoid Null

null is very annoying. Now,Style can help you avoid null values

avoidNull(MayBeNullValue, ()->{DefaultValue});

if MayBeNullValue is null, avoidNull will return value of lambda expression.

##Date

Provides simplification for add/substract of date, and better toString support.

Java built-in Date modification seems to be a little to difficult.

With Style you can write simple and readable Date modifications.

$(date).add(d -> d.day(1).hour(2).minute(3).second(4).milli(5))

.nextYear().nextMonth()

.substract(d -> d.day(5).hour(4).minute(3).second(2).milli(1));

System.out.println($(date).toString("YYYY-mm-dd hh:ii:ss A"));

for toString("") method, Style provide following expressions.

str

meanings

sample

s/S

second

59/3

ss/SS

second

59/03

i/I

minute

59/3

ii/II

minute

59/03

h

12band hour

11/2

H

24band hour

23/2

hh

12band hour

11/02

HH

24band hour

23/02

d/D

date

27/5

dd/DD

date

27/05

m/M

month

12/1

mm/MM

month

12/01

yy/YY

year

15/95

yyyy/YYYY

year

2015/1995

a

am/pm

am/pm

A

AM/PM

AM/PM

###RegEx

Style provide Reg expressions similar to JavaScript

create using regex("/reg expression/flags")

e.g.

regex("/]*>/g").replace("abc", "") // abc

regex("/]*>/").matches("") // true

regex("/]*>/").test("abcdef") // abcdef

regex("/a(bc)(def)(gh)/").exec("abcdefghi") // {bc,def,gh}

###Comparable

Usually we only need to compare two Comparable which is bigger/smaller, but don't need to know how bigger/smaller it is.

e.g.

$(Comparable).eq/ne/lt/gt/le/ge(T)

// boolean : equal/not equal/littler than/greater than/littler or equal/greater or equal

Also,alias like neq,lte,gte are provided.

###Rand

Usually we don't simply get a double from between 0 and 1

Style provides some functions that often used.

rand(100) // 0 <= Integers < 100

rand(0.125) // 0 <= Doubles < 0.125

rand(150, 200) // 150 <= Integers <= 200

rand(0.875, 1.0) // 0.875 <= Doubles < 1.0

rand(string, 50) // based on string, build a random serie with 50 chars

rand(string, 15, true) //based on string, build a random serie with 50 chars that are no repeating chars

rand(string, 15, true, true) //based on string, build a random serie with 50 chars that are no repeating chars after ignoring cases.

###String

We usually have to join strings. C#(.NET) provide a simple way of joining strings. Style learnt from it.

e.g.

$("hello, my name is {0}, let's write java with {1}!").fill("cass","Style");

will return :

"hello, my name is cass, let's write java with Style!"

If you packed the variables to an object, Style provide another way :

e.g. a class Sample

class Sample {

private String name;

private int age;

public String sex;

public Sample(String name, int age, String sex) {

this.name = name;

this.age = age;

this.sex = sex;

}

public String name() {

return name;

}

public int getAge() {

return age;

}

}

You can write:

var sample = new Sample("cass", 20, "male");

System.out.println(

$("My name is ${name}, I'm ${age} years old, and I'm ${sex}.")

.from(sample));

will return

My name is cass, I'm 20 years old, and I'm male.

Comparating operation between strings can take time. string provides unique object represents a string, with which the comparation can be done simply comparing the reference.

$("abc")==$("abc")

would return true

##JSON

You can create a JSONLike object from a json-like Object array.

e.g. you can create a JSONLike object like this:

map(new Object[]{

"name", "cass",

"age", 20,

"sex", "male"

});

JSONLike extends LinkedHashMap

##join

Sometimes we need to sort elements in many lists but don't want to change each list's size. You can use join

when you join lists, a proxy list will be generated, it doesn't support any methods that would cause the size changing. And all operations will be directly operate on proxyed lists.

List joinedList = join(list1, list2, list3, list4, ...);

Collections.sort(joinedList);

// list1, list2, list3, list4, ... will be modified.

##PathMapper

Store objects in the format of 'path'

The paths are separated by '.'

It's based on ConcurrentHashMap,

keys of the values to store are '$value'.

put:

mapper.put("a.b.c", "i am a.b.c");

or

mapper.get("a.b", ()->"abc");

get:

mapper.get("a.b.c");

The based map would be:

{a={b={c={$value=i am a.b.c}, $value=abc}}}

#Appendix

##last loop result

For, For-to-step, While, forEach/forThose loops all have return values.

when a loop finished, it may return a result to the loop controller.

Loop controllers store a value called 'last loop value'.The controller examine the result from loop,

if it's not null, overwrite the 'last loop value' with received result. if it's null, the controller ignore the null value and goes on.

Loop controller is not a class, it's a method. More specificly, Style.For(i,c,inc,loop) and Style.While(c,loop). They are bases of most loops in Style.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值