能力有限,可能有错漏,欢迎大家在评论区指正。
基本的代码格式如下
public class Main{
public static void main(String[] args){
System.out.println("Hello World!");
}
}
下面来个简单的鸡尾酒排序算法,按照文件名的字典序排序文件
import java.io.File;
public class Demo {
void sort(File fs[]){//按照文件名的字典序排列文件
String ss[]=new String[fs.length];
for(int index=0;index<fs.length;index++){
ss[index]=fs[index].getName();
}
outmost:
for(int index=0,a=0,b=fs.length-1;true;index++){
if(index<b){
if(ss[index].compareTo(ss[index+1])>0){
File f=fs[index];
String s=ss[index];
fs[index]=fs[index+1];
ss[index]=ss[index+1];
fs[index+1]=f;
ss[index+1]=s;
}
}else{
if(--b>a){
for(index=b;true;index--){
if(index>a){
if(ss[index-1].compareTo(ss[index])>0){
File f=fs[index];
String s=ss[index];
fs[index]=fs[index-1];
ss[index]=ss[index-1];
fs[index-1]=f;
ss[index-1]=s;
}
}else{
break;
}
}
if(++a<b){
index=a-1;
continue;
}else{
break outmost;
}
}else{
break outmost;
}
}
}
}
}
这代码读起来很顺眼吧?上面的代码有一个毛病,那就是如果数据本身就是有序的,仍然要被固定比较n多次,但如果输入数据是无序,那就毫无影响,也有一些人在鸡尾酒算法中添加了一些逻辑,数据是有序或部分有序的,可以提前结束比较
这是效果图,虽然不是同一个代码,但与上面一样的,只不过多写了几组
当然这个软件没有圆角矩形,就像我的昵称一样,我不喜欢圆角矩形
java敲代码是有一些技巧的,对编程有一定帮助
1,检查右花括号前后的代码与注释:
如非必要,右花括号前后少放代码与注释,如果有的话,尽量把它上移;
把注释放在左花括号后或独占一行是不错的选择
但也有例外,比如代码中有很多的for套娃,此时可能需要在右花括号后标注是否为循环结构代码块,方便阅读。
2,检查右花括号前后的break与continue,break与continue提前写好:
在大量for/while/do-while循环的套娃中,如果产生异常运行结果,一般首先排查break,continue是否丢失,再检查具体的运行逻辑
3,循环早归(continue)早退(break):
在大量for/while/do-while循环的套娃中,如果能够及早调用break与continue,那就及早调用把逻辑交给外层循环处理
4,适当复用重复的代码段
5,单个java源代码文件不要写得太长:
一般不超过3000行,ide在编译项目时只会编译变更的代码文件,其它的代码文件使用缓存,把所有代码放在同一文件中会拉慢编译速度
关于变量的命名:
系统即将进入的下一个状态,叫做次态,它可以是一个多值的叠加态,多值的叠加态比单值的确定态信息量更低,所以可以用一个变量来代表这个次态
系统当前的状态,叫做现态,因为同样的原因,所以可以仅仅一个信息量不高的变量就可以代表这个现态
系统最近的过去的状态,叫做往态
不确定态,是一种非叠加态,也非确定态的态,是一种不可用态,暗示只能被写,不能被读。在系统(程序 )一开始时,所有的态(变量)都是不确定态,只有逻辑的具体运行产生的观测态和操作态才能使不确定态坍塌(实际上java的变量都是有初始值的,比如boolean的初始值是false,int的初始值是0,引用类型是null)
在系统的变化过程中,较晚摆脱不确定态的,叫变生态
如果定义的类中有大量的变生态成员,需要适当创建新类用于存放这些变生态,联系性强的变生态要处于同一个类中
varWill//代表次态
varNow//现态
varOld//往态,有时用varRecent表示
varLim//临界态
varMin//限定
varMax//限定
varSrc//源,src即source
varDst//靶,dst即destination
varSaved//系统过去某一个时间的状态
methodRecur//递归函数
有人认为java变量和函数命名不要用下划线,但我认为不用这样,比如说判断实例类型并强制转换,我有时就是像这样写的,用于表示局部关联紧密的态:
if(animal instanceof Monkey){
Monkey animal_=(Monkey)animal;
//......
}
如果某一变量var与方法method联系紧密,可以把它写成method_var,后期改代码一看就知道它是被方法method所使用的
次态的使用,举个例子,有一张图片,宽iw,高ih,还有一个控件,宽vw,高vh,缩放图片到控件中,但不要拉伸变形,计算图片缩放后宽高:
int iwWill=vw;
int ihWill=(int)(ih*(iwWill/(double)vw));
if(ihWill<=vh){
iw=iwWill;
ih=ihWill;
}else{
ih=vh;
iw=(int)(iw*(ihWill/(double)ih));
}
枚举
enum是一个不太靠谱的东西,因为实际开发中有很多枚举是难以命名的,或者说枚举太多,导致只能用一个int变量来枚举,通常我把它命名为ctrl并作为一个类成员
代码的阅读:
读代码的难度和写代码是相当的,因此不要试图去理解全部的逻辑,按照自己的需求去寻找相应的逻辑起点-终点就可以了
下面这些读代码套路是我平时用的,这东西是很抽象的,故而有些复杂的概念,我不知道它们对你有没有用,它们正在改进之中。
逻辑特征态,是由逻辑转换而来的,但它并不是逻辑,而是数据,并且这个数据是一个叠加态,比如说代码:
if(a==8){a=9;}//变量a是int类型
它可以转换出两个逻辑特征态,用伪代码表示的话就是:
fi(a==8);a=9;//将a写为8,再写为9
fi(a!=8);
其中fi函数的作用不是像if那样读变量,而是写变量,而且它可以写叠加态,以达到表示一个叠加态的目的,在逻辑特征态中,fi写出的数据叫原型态,如果有来自系统外的干涉,叫观测态,fi(a!=8)将a写为叠加态,取值为0x0~0xffffffff中除了8以外的所有值的叠加态,a=9表示遮盖态,如果有指向系统以外的干涉,叫操作态
因为逻辑的自身的设计错误而导致某个逻辑片段意外的没有被调用,叫偶断,意外的被调用,叫偶通,它们都是由逻辑中第一个错误的操作态或观测态引起的
查找逻辑的错误,可以通过代码插桩或注释掉一些代码进行,最重要的是仔细观察bug出现的时机,缩小代码范围,不然到时候在一大堆代码缩进中查bug,很容易搞不清楚查找到了哪里,分析逻辑的错误,实际上是在思考特征态,主要检查观测态是否与操作态冲突!因此不要试图思考某一瞬间变量的具体取值