用了java从入门到精通和Java核心技术的基础篇,准备第一本为主,第二本为辅,实践加上理论的去学习。
java是用类组成的。每个类都要有一个主函数。含有main方法的类称为Java主类。
这个是声明在主函数外面的
这个是申明在主函数里面的。
里面的变量定义可以边定义边操作:long s1 = s2+s3+s4;
final <类型> <变量名>=<值>
在Java中,变量名和变量名所对应的数据是存放在不同的地方的。
一般申明在主函数外部,这个可以参考C语言。
这个就是输出的语法。这里有个问题,能不能一次性输出一大堆。
打印的时候可以类似于python里面,用+这个符号,这个跟C语言有点不大一样。
注意,整数类型不能以0开头,八进制以0开头,十六进制以0X开头。
整数类型的名称是和他们能表示的进制位有关系,byte是八位,依次成倍数增长。可以表示从负数到正数。
字符型 一个字符占两个字节的空间java里面和C以及C++是一样的,可以将字符串看作整型,而且还是无符号数。具体申明方法char x='<字符>'这个就是单个字符的申明。多个字符用双引号。转义字符,这个和python一样,知识继承就好了。 布尔型 小写就是将目标类型用圆括号括起来,然后跟上变量。
Java中是区分双引号和单引号的目前没搞懂,为什么main里面要有一个String[] args
以及stactic是什么意思?是全局变量的意思吗?
final <类型> <变量>
在整个类中都适用的变量叫做成员变量。成员变量中包含两种变量:
静态变量 static <数据类型> <变量>静态变量可以在整个类中被访问,同时,还可以用<类名>.<静态变量>来访问。由于静态全局变量的作用域限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。 static全局变量与普通的全局变量的区别是static全局变量只初始化一次,防止在其他文件单元被引用。 实例变量只在当前的类里面有效,一旦跳出了这个类,就无效了。
这里面最重要的就是自增和自减,这个参考C语言。
这个和其他语言是一样的,参考python和c语言。
这个就是:
<< 左移>>右移,并且,最高位和之前的最高位有关系。在书pdf93,有需求了再看。这个比较的关键,因为,这个可以减少空间复杂度。
boolean b = 20<45?true:false
上面这个例子只是一部分,当然我们可以定义其他类型来完成三元运算。
即满足条件就是true的部分,否则就是false的部分。
从低级类型向高级类型的转换,这个是由系统自动执行的,不需要我们人为的来完成。
这里就有一个转换表:
当我们把高精度的数据赋给低精度的数据的时候,我们就要用显示类型转换了。这个和C语言是不一样的。
这个和上面那个刚好是相反的。
(<类型>)<变量>
这个和C语言一样
这个就是/** */中间的被视为文档注释。
这个就是在函数总又加了一对大括号,在大括号里面会新开辟一个命名空间,一旦这里面的变量到了外面使用,就会报错。
这里面就是if语句了,这个是语言中非常重要的环节之一。这个和C语言很像。
switch也是一样的。
for语句和循环语句,以及do while语句,这个和C语言是一样的,我们沿用就行了。
其中有一个foreach语句,这个是for语句的精髓。
int arr[]={1,8,9} for(int x:arr){ System.Out.printIn(x) }这个变量的定义要和数组中的保持一致。
java中有标签语法,就是说内层循环可以直接结束外层循环,当指定标签的时候。
Loop:for(int i = 0;i<=10;i++){ for(int j = 0;j<=5;j++){ if(j==3){ break Loop; } } }类似于这样,就可以结束外层的循环嵌套。
这个我看上去和python有点像,又和C语言有点像。
这个是基于序列之上的。
char a[]={'g','o','o','d'}; String s = new String(a,<>,<>);//第一个参数是起始坐标,第二个参数是取的的个数。 //或者直接这么定义 String s = new String("student");String是字符串的意思,然而,char是字符的意思。
或者直接定义String <变量>;
直接用加号。
str.length();str指的就是字符串。
indexOf;查找字符串第一次出现的位置
lastIndexOf;查找字符串最后出现的位置
str.charAt(<坐标>);
str.substring(int x);这个就是从指定的字符串索引开始往后截取。当然,也可以定义结束的位置。取头不取尾。
str.trim();这个因为是类写的,所以有多态。
str.replace(<old>,<new>);
str.startsWith(<期望字符>);
str.endsWith(<期望字符>);
这两个方法返回的都是布尔值。
str.equals(<String otherstr>);
下面这个方法是忽略大小写。
str.equalsIngnoreCase(<String otherstr>);
判断两个字符的前后位置
str.CampareTo(<另一个字符>)
转换大小写
str.toLowerCase()
str.toUpperCase()
这个比较的管用,在处理字符串方面用的很多,至少爬虫这方面我是深有体会:
str.split(<要分割的字符串>)同时,加个逗号后面跟整型,可以标识分割几次。
这个等用到的时候再说,练起来没有多大的意义。
但是常规个字符格式化是要记住一些的。这个就跟C和python中的格式化输出一个道理。
这个就跟内存有关系了,在python中我们避免一直用str += str的原因就是,这样会不停的创建出一个新的内存,时间复杂度很高。Java中有类似的机制避免这种情况。
Java中提供了一种字符串生成器来减少系统的开销。
这个我觉得它应该是使用了一种花销平坦的机制,和python的列表是很像的。
StringBuilder <变量> = new StringBuilder("");不过,这里建议使用变量名是builder,这个可能是一个规定。
str.toString();
str.insert(int start,int end);
这样就可以在字符串中插入
str.delete(int start ,int end);
数组有一维的和二维的等等。在Java中,我们每一个都是一个对象,所以我们在申明了数组的变量之后,还要new一个对象,这样的话,系统才会给它分配内存,不然这个变量名就是无效的,下面举一个例子,我们来创建一个一维的int类型的数组。
int x[]; x = new int[6];现在才算真正的创建了一个一维的数据,长度是6。
当然,上面的语法是可以合起来的:int <变量名>[]=new int[6]
int <>[]={<元素>,...,<元素>};
int <>[]=new int[]{<元素>,...,<元素>};
这个也是可以的。
数组的访问跟python的一摸一样,就是用下标的方式进行访问,这里我觉得可以用none乘以任意值来初始化数据,当然,这个是我的猜想。
这个初始化和一维是一样的,只不过,我们还要不停的为两个维度的数组分配内存
int a[][]=new int[2][4]; a[0]=new int[5]; a[1]=new int[2];int a[][]={{<元素>},...,{<元素>}}这个初始化和C语言是一样的。
这个参考当时的C语言。
这里采用的是拆解遍历法
for(int xi[]:xx){ int j=0; for(int e:xi){ if (i==1&&j==2){ System.out.println(e); break; }else { System.out.println(e); j++; } } i++; }里面用的就是java中的foreach语句。
第一个循环是不停的把二维变成一维;第二个循环就是把一维变成一个个的元素。这个循环就是在不停的把数据降维度输出。每次都下一个维度。
我们可以用print这个函数来让它在同一行输出。
我们可以使用fill方法来对数据进行填充。举个例子来讲:
<>.fill(<类型> <数组>[],<填充的东西>)这个只是一个例子,这个fill可以用一个值填充整个数据。
package cd.idcast; import java.lang.reflect.Array; import java.util.Arrays; public class 数组的填充 { public static void main(String[] args) { int arry[]=new int[8]; Arrays.fill(arry,5); for(int i=0;i<arry.length;i++){ System.out.print(arry[i]+", "); } } }我们发现,填充这个方法,用的是Arrays对象。当然,填充也是可以指定范围的,这个可以类似于替换数组中的元素。
Arrays.fill(<数组变量>,<起始位置>,<结束位置>)这个就是指定位置的填充,也可以理解为替换。
Arrays.sort(<对象>)
这个就要用到另一个对象了。
copyOf(<数组对象>,<复制的长度>)
copyOfRange()这个就是指定数组的指定复制范围。
binarySearch(Object[] a,int fromIndex,int toIndex,Object key); /*其中,a 表示要进行查找的数组,fromIndex 指定范围的开始处索引(包含开始处),toIndex 指定范围的结束处索引(不包含结束处),key 表示要搜索的元素。 在使用 binarySearch() 方法的上述重载形式时,也需要对数组进行排序,以便获取准确的索引值。如果要查找的元素 key 在指定的范围内,则返回搜索键的索引;否则返回 -1 或 “-插入点”。插入点指要将键插入数组的位置,即范围内第一个大于此键的元素索引。*/思想就是,不停的从头开始对比,但是交换的次数是越来越少的。因为每次交换都能保证最大的一定在最下面。当然,这个是升序,我们当然可以降序排列
package cd.idcast.num; public class 冒泡排序 { public static void main(String[] args) { int[] array = {63,5,24,1,100,3}; //冒泡排序 } public void sort(int[] array){ for(int i = 1;i<array.length;i++){ for(int j=0;j<array.length-i;j++){ if(array[j]>array[j+1]){ int temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } showArray(array); } } public void showArray(int[] array){ for(int i:array){ System.out.print(">"+i); } System.out.println(); } }这个就是从最后一个位置开始,每次选出最大的一个,然后和位置交换,这个位置呢,就是array[array.length-i],这个位置每循环一次就会减一。为什么说最开头的这个不换了呢,因为当后面位置的数全是最大的时候,那么第一个数一定是最小的。
package cd.idcast.num; public class Select_order { public static void main(String[] args) { int[] array = {96,52,18,2,1,0}; Select_order sorter = new Select_order(); sorter.sort(array); } public void sort(int[] array){ int index; for(int i=1;i<array.length;i++){ index = 0; for(int j=1;j<=array.length-i;j++){ if(array[j]>array[index]){ index = j; } int temp; temp = array[array.length-i]; array[array.length-i] = array[index]; array[index] = temp; } pprint(array); } } public void pprint(int[] array){ for(int x:array){ System.out.print(x+" "); } System.out.println(); } }类是封装对象的载体,我们不能把单一的事物称为类。
现在还没有办法理解这个public的具体含义,以及public和private是怎么协同工作的。
我们先要从设计一个类开始,然后再着手的去实现类里面的方法。
我们通常用类名来申明一个对象,同时,要配合上new来让该对象能够不停的被访问:Book one_editor = new Book()
我们引用的类实例都是外部的,是一个具体的,而且,每个不同的变量指向不同的类实例。
我们都会翻译,UML是统一建模语言,是一种可视化的面向对象建模语言,是一种用来对真实世界物理进行建模的标准标记,用图形方式表现典型的面向对象系统的整个结构。它的作用域不局限于支持面向对象的分析与设计,还支持从需求分析开始的软件开发的全过程。
https://blog.csdn.net/xdd19910505/article/details/18698825/
上面的网站中有详细的说明。
不管前面的权限修饰符是public或者是private,这个都是成员方法。成员方法的声明格式是:权限修饰符 返回值类型 方法名(参数类型 参数名){//方法体}
这个我觉得如果用python中的类来理解会好一点。
在Java中,权限修饰符有三个:
publicprivateprotecteddefault修饰的成员:该成员对同一个包中的类都可见。如果是public,那么这个就属于公共的,也就是说任意地方都能访问到。
如果是private的话,这个就跟python中类里面,用下划线定义的变量或者是函数,是私有的,它存在在本类当中,但是不能够被外界访问。
如果是protected的话,那就是只有其他包不能访问,同包里面,或者同一个文件里面都是可以访问到的。
在类中,如果学过python,那么我们将this映射成python中的self,也就是实例对象本身。我们将private映射成用“_”开头的私有属性或者函数,也就是只有内部才能调用和访问,子类以及其它是访问不了的。
如果一个类前面没有任何的权限修饰符的话,那么我们将这个类默认成protected类型的类,也就是只有本包和子类可以访问该类。本包外的就不行。
在类中的方法如果不定义权限修饰符,那么会默认是public,因为类的权限设定会影响里面的权限设定。
这个就跟python中的命名空间是一个概念,在该命名空间中,变量的名称是不能够重复的,但是在不同的作用域里面,变量的名称确实是可以重复的。这个就跟在两个for循环里面用同样的变量i是一个道理。
局部变量在调用结束后就会被销毁。
这个就相当于python中的self,而且,这个可以直接作为对象返回。
这个是在项目中创建public <类名称>(){//函数体}这个可以没有返回值,同时,如果没有参数的话,我们可以在函数体中的第一句加上this("<参数>"),但也只能是第一句。
这个就是可以让别的类也访问的常量类型,用于节省内存。
用类名加上点来调用方法。
我觉得这个跟python中的init就很像。
这个就是前面的权限修饰符。
package cls_test; public class lei_tes_2 { public lei_tes_2(){ System.out.println("Hello"); } public static void main(String[] args) { new lei_tes_2(); } }在这里面,我们发现,在主类里面创建了一个lei_tes_2,它的构造方法和它是同名的。
构造方法就是相当于初始化方法,这个会在主函数中一旦遇到了new之后自动调用,构造函数的方法就是在主函数外面创建一个同名的类名,里面定义其它代码。
前面是比较地址是否相等,后者是字符串的方法,比较两个字符串是否相等。
将对象赋值为null或者用finalize()方法都是可以的。同时我们可以用System.gc()来强制回收对象。
每个类中,只有一个main方法,同时,有很多的不同类,这些类最终会在main方法中被调用。要想创建一个完整的程序,就要将他们结合到一块。
有些情况下,我们需要将数字作为对象进行处理,所以这个时候,我们就需要包装类了。
在这个类里面就有很多的方法:
其中有很多转换的方法在pdf189页,这里举一个例子:
package Pack_class_test; public class Integ { public static String[] num = {"45","56","343"}; public static void main(String[] args) { int sum = 0; for (String s : num) { int x = Integer.parseInt(s); sum += x; } System.out.println(sum); } }这个就是将数字当作对象来处理了。
这个就是,如果我创建了一个Boolean的对象,那么如果对象不是true(忽略大小写),那么返回false。
其他方法和上面是类似的。
package Pack_class_test; public class Integ { public static String[] num = {"45","56","343"}; public static void main(String[] args) { int sum = 0; for (String s : num) { int x = Integer.parseInt(s); sum += x; } System.out.println(sum); Boolean bool = Boolean.valueOf("type"); System.out.println(bool); } }其他的方法是类似的,我们只需要查书就行了。
这个相当于python中的format,非常的有用,尤其是在处理一些别的方面的时候。
其他的书中也有介绍,用到的时候再具体的查书。在PDF199页这里。
<对象>.setGroupingSize(<整型>)
Sting <变量> = <对象>.format(<整型>)
用到了查书。PDF203页。
这个根据以往用python的经验来讲,还是比较重要的。
这个模块呢,只能产生0-1之间的数,所以我们用这个的时候,需要乘上相应的值来达到任意区间随机数的目的。
package Pack_class_test; import java.text.DecimalFormat; public class NumFormat { static public void FormatNum(String pattern,double num){ DecimalFormat myformat = new DecimalFormat(pattern); String nums = myformat.format(num); System.out.println(nums); } static public void RandomNum(double num1,double num2){ int s = (int)(num1)+(int)(Math.random()*num2); System.out.println(s); } public static void main(String[] args) { FormatNum("000.00kg",185.6989); FormatNum("#####.##",15.3); FormatNum("#.###%",0.236); RandomNum(12.6,89.898989); } }我们也可以用它来生成随机的字符,这个和上面的方法是一致的,只不过,我们用的是char类型。
Random r = Random();
后面就可以调用里面的方法了,这个书中都有列出,这里略过,要用的时候查文档就行。书PDF208页。
BigInterger可以表示任意大小的整型。
里面的算术运算是以对象的形式进行的,我们来举几个例子:
package Pack_class_test; import java.math.BigInteger; public class bigNum { public static void main(String[] args) { BigInteger bigs = new BigInteger("45"); System.out.println(bigs.add(new BigInteger("69"))); } }其他的和这个类似。
在这个类中,不同的传参转换的结果是一样的,我们可以传double类型,也可以传string类型。
package Pack_class_test; import java.math.BigDecimal; import java.math.BigInteger; public class bigNum { public BigDecimal add(double var1,double var2){ BigDecimal d1 = new BigDecimal(Double.toString(var1)); BigDecimal d2 = new BigDecimal(Double.toString(var2)); return d1.add(d2); } public static void main(String[] args) { // System.out.println(bigs.add(new BigInteger("69"))); // BigDecimal dd = new BigDecimal("15.26541"); // System.out.println(dd.add(new BigDecimal("8861.165489461"))); // System.out.println(BigCal); bigNum b = new bigNum(); System.out.println(b.add(1254.156,896.3486416)); } }子类中可以重构父类的方法和参数,但是除了权限修饰符为private的除外,同时,重写时不能降低权限的修饰范围,也就是提升是可以的。
Java中,用extends来表示继承类
class Text2 extends Text1这里我们发现,是前面的继承了后面的
同时我们用super();来调用父类方法。
super();//这个是调用父类的构造方法。 super.<方法>();使用父类方法的时候要注意,如果定义的是static类型的函数,那么不用加super,直接调用即可。
实例化的时候,父类先实例化,然后再是子类。
这个是一个基类,我们创建的Java类都默认继承了它。
这个方法是类自动继承的,我们通常重写他,它会在类被实例化之后自动调用。同时,它可以让类对象作为一个字符串输出。
在实例化的过程中,equals是默认"==",所以我们要重写它。
也就是子集向全集转化的时候,就可以实现向上转型。
static类型的函数,只初始化一次,所以继承后可以直接调用。
这个时候必须使用显示类型转换,不然就会报错。
<类名> <变量> = (类名)<变量>
这样配合上面的转型,可以让程序变得更加的健壮。
package Pack_class_test; class QQQ{ public static void draw(QQQ q) { System.out.println("来了老弟"); } } class Square extends QQQ{ public static void gg(){ int i=0; System.out.println("我是方"); } } class Anything{ } public class Judge_ex extends QQQ{ public static void main(String[] args) { QQQ p = new QQQ(); if(p instanceof Judge_ex){ System.out.println("没错,现在我要开始转换了"); Judge_ex q = (Judge_ex)p; } if(p instanceof Square){ System.out.println("是方的"); Square q = (Square)p; System.out.println("转型完成"); } } }一个类里面,Java允许有相同名字的不同函数,只要这些函数的类型,传参等等不一样,JAVA就能识别他们,这样方便我们管理代码。
同时,里面有一个任意传参的语法:
<类型>...<变量>这个就相当于数组了。
package Pack_class_test; public class ReloadFuc { public static double add(double...num){ double sum=0; for(double x:num){ sum +=x; } return sum; } public static int add(int...num){ int sum = 0; for (int x:num){ sum +=x; } return sum; } public static void main(String[] args) { System.out.println(add(1,5,6,8)); System.out.println(add(1.2,5,8.6,45)); } }利用了向上转型的特性,比如说绘制四边形,我们定义一个大类,然后让里面的子类同变成参数传递进draw这个大类里面,然后通过不同的限制来处理不同的四边形绘制,这个大概就是多态的思想。
package Pack_class_test; public class Duotai { //四边形类 private final Duotai[] qtest = new Duotai[6]; private int nextindex = 0; public void draw(Duotai q){ if(nextindex<qtest.length){ qtest[nextindex]=q; System.out.println(nextindex); nextindex++; } } public static void main(String[] args) { Duotai q = new Duotai(); q.draw(new Sq()); q.draw(new Parallelogramgle()); } } class Sq extends Duotai{ public Sq(){ System.out.println("我是正方形"); } } class Parallelogramgle extends Duotai{ public Parallelogramgle() { System.out.println("我是长方形"); } }这里我们就可以看到,我们在主类方法里面,就实现了多态的运行。
多态和接口的技术相结合,就能让代码变得更加的健壮。
在Java中,是不允许多重继承的,但是呢,如果调用接口就是可以的:
class <类名> implements <接口>,<>...<>{ }接口之间也是可以继承的。这个继承方法和类是一样的。
interface <> extends <>{}