Java基础笔记
Java认识:
简单而言,使用JDK(开发工具包)开发完成的Java程序,交给JRE(运行环境)去执行,再一个,JVM保证了Java语言的跨平台性。(JRE是包括JVM的,因此,要开发一个好的好的java程序,只需要装JRE就可以了)
1、变量组成元素:英文字母、数字、$和_;当然开头不能是数字;
2、 包:全部用小写;
类或者接口:单个单词的话,首字母大写;多个单词的话,只要首字母大写;
方法或者变量:单个单词的话,首字母小写,多个单词的话,只需要首单词小写,其它单词首字母大写;
常量:单个单词的话,全部大写,例如:PI;多个单词的话,所有字母都要大写,中间用_隔开;
3、不同进制的数据表现:
二进制:由0、1组成。以0b开头;
八进制:由0、1.。。。。7组成,以0开头;
十进制:由0、、、9组成,默认整数就是十进制;
十六进制:由0、、、、9、a、、、f(大小写都OK)组成,以0x开头;
4、java中的数据类型:数值类型、引用类型;
数值类型:
整型: 占的字节
byte 1
short 2
int 4
long 8
浮点型:
float 4
double 8
字符型:
char 2
布尔型:
boolean 1
注意:整数默认都是int类型; 浮点型默认都是double类型;
建议:在定义long类型的时候,在末尾加上"L"。例如:long j=1000000000000L;(因为默认情况下,整数都是int类型)
建议:单精度浮点数用f或者F结尾,例如:float a=1.345;(否则会报告精度丢失,其实就是浮点型默认是double类型, 然而你将double类型转换为float类型时,如果不是强制类型转换,可能会丢失精度)
5、默认转换:(从小到大)
byte、short、char、int、long、float、double;
byte、short、char之间不相互转换,它们参与运算首先转换为int类型。
6、System.out.println('a'+1); //输出:98 说明a的ASCII是97;A的ASCII是65;0的ASCII是48;
7、short s = 1; s = s + 1;有没有问题?如果有怎么解决?
有问题,加上强制类型转换:s=(int)(s+1);
short s = 1; s += 1;有没有问题?如果有怎么解决?
这个没有问题。
8、&与&&的区别?|与||的区别?
&&具有短路效果,只要左边是false,右边就不执行了。
同理,||也是具有短路的效果,只要左边是true,右边就不执行了。
而,&和|都要执行完两边的逻辑表达式,才会得出结果。当然&和&&的最终执行结果是一样的;
|和||的最终执行结果也是一样的;
9、位运算符??
要进行位运算,首先要把数据转换成二进制。
&(与)、|(或)、^(亦或,相同为0,不同为1)、~(按位取反)这四个是位运算符;
当这几个运算符的两端是布尔值时,则进行逻辑运算,当它们两端是数值时,位运算;
按位取反:例如:~3---->-4
00000000 00000000 00000000 00000011 先按位取反,得到补码
11111111 11111111 11111111 11111100(补码),再得到反码
11111111 11111111 11111111 11111011(反码),再得到原码
10000000 00000000 00000000 00000100原码--->-4
例如:System.out.println(3 & 4); //输出的结果是00000000 00000000 00000000 00000011(3)
00000000 00000000 00000000 00000100(4)
00000000 00000000 00000000 00000000(0)
所以结果是:0
10、原码、反码、补码???正数的符号位是0,负数的符号位是1。
正数的反码和补码与原码相同。
负数的反码是对其原码逐位取反,但符号位除外。
负数的补码是在其反码的末尾加1。
11、十进制转换为二进制(带小数点)
6.125--->二进制 6-->110 0.125-->0.125 * 2=0.250 取整数位:0
0.250 * 2=0.50 取整数位:0
0.50 * 2=1.0 取整数位:1
其实结束的标志就是小数位为0
二进制转换为十进制(带小数点)
110.111---->十进制 110-->6 0.111---->1*2^-1 + 1*2^-2 + 1*2^-3=0.875
so,110.111--->6.875
12、java中将String类型转换位int类型:Integer.parseInt("4");//参数只能是数字,否则抛异常
产生随机数:int num=(int)(Math.Random()*5); //这会产生一个0~4的随机数,Math.Random()默认产生
0~1的随机数,并且是double类型的,因此,这里需要强转。
13、collection中的set函数。(没有重复)
14、类中局部变量和成员变量的区别:
1)、存在的位置不同:局部变量在类中的方法内,成员变量在类中,但是在方法外;
2)、在内存中的位置不同:局部变量存在于栈中,成员变量存在于堆中。
3)、生命周期不同:成员变量随着对象的创建而存在,随着对象的消失而消失;局部变量随着方法的调用而存在,随着方法调用完毕而消失。
4)、初始化值不同:成员变量有默认初始化值,局部变量必须定义,赋值,才能使用。
注意:在方法内可以起和成员变量同名的局部变量,但是在使用的时候,遵循就近原则。
15、匿名对象:没有名字的对象。例如:直接写new Student().show();
匿名对象运用的场景:
A:调用方法,仅仅调用一次。注意,调用多次的时候不适合;
匿名对象的好处就是,一旦使用完就被GC回收。
B:匿名对象可以作为实际参数传递。
16、封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
17、static的特点:(在静态方法中没有this关键字,其实就是静态方法不能调用非静态变量
或者方法)
A:随着类的加载而加载;
B:优先于对象而存在;
C:被类的所有对象所共享;
D:可以通过类名调用;(其实也可以被对象调用,推荐用类名调用)
18、java中实现继承:通过extends关键字
继承的好处:提高了代码的服用复用性、提高了代码的维护性、让类与类之间产生了关系,是多态的前提。
继承也有坏处:正因为类与类产生了关系,所以导致类的耦合性增强了,而我们开发项目的原则就是:低耦合、高内聚; 耦合:类与类的关系; 内聚:就是自己完成某件事的能力。
19、java中继承的特点:
1)、只支持单继承,不支持多继承;
2)、支撑多层继承(继承体系);
java中继承的注意事项:
1)、子类只能继承父类的所有非私有成员(成员变量,成员方法);
2)、子类不能继承父类的构造方法,但是可以通过super关键字去访问父类的构造方法;
3)、切记:不可因为部分功能盲目使用继承。
判断是否应该使用继承的原则就是:看看谁是谁?例如:student是Person;apple 是fruit等;
20、this和super的区别:
1)、this代表本类对象的引用;
2)、super代表父类存储空间的标识(可以理解为父类的引用,可以操作父类的成员)。
21、继承中构造方法中的关系:
A:子类中所有的构造方法默认都会访问父类中空参数的构造方法;
B:为什么呢?------因为子类会继承父类中的数据,可能还会使用父类中的数据,所以在
子类初始化之前,一定先完成父类数据的初始化。
注意:子类中构造方法的第一句默认都是调用父类的构造方法,即super();
22、如果父类中没有无参构造函数,只有有参构造函数,而子类中有无参构造函数,也有有参构造函数,那会
出现啥状况?
这会在父类初始化的时候出现错误,因此可以用super显示调用父类的带参构造方法,或者用this关键字显示
调用本类的其他有参构造方法。
也就是说,无论如何子类都要有一个去访问父类的构造方法,否则父类就无法完成初始化。
注意事项:this()或者super()调用构造方法的时候,要放在第一个语句。
23、一个类的静态代码块(随着类的加载而加载)、构造代码块、构造方法的执行流程;
静态代码块》》构造代码块》》构造方法
24、方法重写的注意事项:
A:父类中私有方法不能被重写---------因为父类中私有方法子类根本无法继承;
B:子类重写父类中的方法时,访问权限不能再低,最好就是一致。
C:父类中的静态方法,子类也必须通过静态方法重写
其实,这个算不上方法重写,但是现象确实如此。
子类重写父类中的方法,既然是重写,那就最好两个方法除了方法体之外,其他全部一样。
25、final可以修饰类、方法、变量
特点:
final修饰类:该类不能被继承。
final修饰方法:该方法不能被重写。
final修饰变量:就变成了常量。
final修饰基本类型的变量:基本类型的值不能发生任何改变;修饰引用类型:引用类型的地址值不能发生改变,
但是该对象的堆内存里的值是可以改变的。
final修饰的变量只能赋值一次。
26、多态的前提:
A:要有继承关系;
B:要有方法重写;
C:要有父类引用指向子类对象;
多态中的成员访问特点:
A:成员变量
编译看左边,运行看左边
B:构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化;
C:成员方法(由于成员方法存在方法重写,因此运行看右边,具体看看下面的例子:)
编译看左边,运行看右边
D:静态方法
编译看左边,运行看左边(静态和类相关,算不上重写,所以访问的还是左边的)
例如: class Fu{
int num=10;
public void show(){
System.out.println("show FU");
}
public static void method(){
System.out.println("method Fu");
}
}
class Zi extends Fu{
int num=20;
public void show(){
System.out.println("show Zi");
}
public static void method(){
System.out.println("method Zi");
}
}
class Demo{
public static void main(String[] args){
Fu f=new Zi();
System.out.println(f.num); //10
f.show(); //show Zi
f.method(); //method Fu
}
}
27、抽象类的特点:
A:抽象类和抽象方法必须用abstract关键字修饰;
B:抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类;
C:抽象类不能实例化, 因为它不是具体的。
D:抽象类的子类,要么也是抽象类,不必实现父类的抽象方法;要么子类是非抽象类,但是
要实现父类的所有抽象方法;
其实:抽象类的实例化是依靠子类来实现的。
成员变量:既可以是变量,也可以是常量;
抽象方法:有。-------用于子类访问父类数据初始化
成员函数:可以是抽象的,也可以是非抽象的。
28、接口的特点:
A:interface关键字 interface 接口名{}
B:类实现接口用implements表示 class 类名 implements 接口名{}
C:接口不能实例化 但可以通过多态进行实例化(也就是实现它的类的对象)
D:接口的子类:
可以是抽象类:没有实际意义;
也可以是具体的类:要重写接口中的所有抽象方法(推荐方案)
接口成员特点:
成员变量:只能是常量,并且是静态的。默认修饰符:public static final,建议:自己手动加上;
构造函数:接口没有构造函数;
成员函数:只能是抽象方法。 默认修饰符: public abstract 建议:手动给出
接口与类:实现关系,可以单实现,也可以多实现;
接口与接口:继承关系,可以单继承,也可以多继承。
抽象类和接口的区别:(设计理念区别)
抽象类被继承体现的是:“is a ”的关系。抽象类中定义的是该继承体系的共性功能;
接口被实现体现的是:“like a”的关系。接口中定义的是该继承体系的拓展功能;
29、包的定义:
Package 包名;
多级包用.分隔开
注意事项:
A:package语句必须是程序的第一条可执行语句;
B:package语句在一个java文件中只能有一个;
C:如果没有package,则默认表示无包名;
带包的编译和运行:
A:手动式:
a:编写一个带包的java文件;
b:通过javac命令编译该java文件;
c:手动创建包名
d:把b步骤的class文件放到c步骤的最底层包;
e:回到和包根目录在同一目录的地方,然后运行;
B:自动式:
编译的时候加上javac -d . Demo.java
运行的时候java 包.名字 Demo
30、权限修饰符:
本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private: Y
默认: Y Y
protected: Y Y Y
public: Y Y Y Y
31、修饰符:
权限修饰符:private 默认 protected public
状态修饰符:static final
抽象修饰符:abstract
类(可以用于修饰类的):
权限修饰符:默认修饰符、public
状态修饰符:final //代表啥意思????
抽象修饰符:abstract
成员变量(可以用于修饰类的):
权限修饰符:private 默认 protected public
状态修饰符:final static
用的最多的就是:public
抽象函数(可以用于修饰类的):
权限修饰符:private 默认 protected public
用的最多的就是:public
成员方法(可以用于修饰类的):
权限修饰符:private 默认 protected public
状态修饰符:static final //代表啥意思????
抽象修饰符:abstract
32、内部类位置:
成员位置:定义在成员位置的类叫做成员内部类;
局部位置:在局部位置定义的类被称为局部内部类;(成员方法内)
成员内部类的访问方法:(创建对象方法如下:不能直接创建内部类的对象)
外边类.内部类 对象名=new 外边类().new 内部类();
内部类可以用static修饰,因为内部类可以看作是外部类的成员。
成员内部类的修饰符:
private 为了保证数据的安全性;可以通过创建外部类的对象,然后通过外部类的对象来访问自己
内部的一个方法,这个方法内首相创建了内部类的对象,然后又调用内部类的方法;
注意事项:
成员内部类:
a:内部类和外部类没有继承关系;
b:通过外部类名限定this对象(其实就是内部类要访问外部类的成员变量)
局部内部类:
a:可以直接访问内部类成员;
b:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能;
局部内部类访问局部变量的注意事项:
a:局部内部类访问局部变量必须用final修饰局部变量;
b:为啥呢?
局部变量是随着方法的调用而调用,随着调用完毕而消失,而堆内存的内容(也就是局部内部类的
对象,它很有可能还要继续使用这个变量)并不会立即消失。所以我们加final修饰,加入final修
饰后,变量就变成了常量,既然是常量,你消失了,我在内存中存储的是数字20(或者其他),
所以,我还是有数据可以使用;
33、匿名内部类:
就是内部类的简化写法
前提:存在一个类或者接口
这里的类可以是具体类也可以是抽象类
格式:
new 类名或者接口名(){
重写方法;
}
匿名内部类的本质是:是一个继承了该类或者实现了该接口的子类匿名;
举例说明:
//匿名对象的前提就是有个类或者接口
interface Inner{
public abstract void show();
public abstract void show2();
}
/*
class Outer{
new Inner(){
}
}
*/
class Outer{
public void method(){
/*new Inner(){
public void show(){
System.out.println("show");
}
public void show2(){
System.out.println("show2");
}
}.show();
//当然这里可以直接调用对象的方法
new Inner(){
public void show(){
System.out.println("show");
}
public void show2(){
System.out.println("show2");
}
}.show2();*/
//比较简化的写法就是利用多态,创建子类(实现类)的对象给父类(接口)
Inner i=new Inner(){
public void show(){
System.out.println("show");
}
public void show2(){
System.out.println("show2");
}
};
i.show();
i.show2();
}
}
class Demo{
public static void main(String[] args){
Outer o=new Outer();
o.method();
}
}
34、Eclipse的常用快捷键:
ctrl+shift+f(快速格式化)
alt+/ 辅助提示
导入包 ctrl+shift+O
输出:syso + alt+/
main方法:main+alt+/
单行注释:ctrl+/
取消单行注释:再按一次ctrl+/
多行注释:ctrl+shift+/
一块代码上下移动:alt+上下键
查看源码:选中类名 按f3(或者是ctrl加鼠标点击)
--------------------------------------------------------------------------------------------------------------------------------------------
1、Eclipse的部分快捷键:
alt + shift + s 再按o //有参构造函数
alt + shift + s 再按c //无参造函数
alt + shift + s 再按r //属性
2、Object的几个常用方法:
int hashcode();//返回对象的转换后的实际地址值,是一个整数。
getclass()方法:
student s=new Student();
Class c= s.getclass();
String str=c.getname();
//最后得到的是对象t的全名,即包名+类名;
3、“==”
基本类型:比较两个值得大小是否相等;
引用类型:比较两个引用的指向的地址是否相等;
equals:比较引用类型默认也是比较地址值是否相同,而String类重写了equals()方法,比较的是内容是否
相同;
4、String s=new String("Hello");和String s="Hello"两者有区别吗?
有,前者会创建2个对象,后者创建1个对象;
5、StringBuffer和String的区别:
StringBuffer是线程安全的可变字符串;
StringBuffer的长度和内容可变,而String不能。
因此太多的字符串拼接,用StringBuffer不会浪费太多资源;
StringBuffer的方法:
public int capacity(); //返回当前容量 理论值
public int length(); //返回长度 实际值
StringBuffer的构造方法:
StringBuffer() //无参构造,默认长度是16个字符
StringBuffer(int capacity) //设置初始的长度
StringBuffer(String s) //以给定的字符s来具体给定长度
StringBuffer的几个常用方法:
public StringBuffer append(); //向缓冲区追加各种字符串;
public StringBuffer Insert(参数有多种。。。) //插入(各种插入)
String作为参数传递时,和基本数据类型一样的效果。
6、Arrays类中全是static方法,这个类就是专门对数组进行操作的,在调用的时候通过类名来调用;
public static String toString(参数可以是任意类型的);//将任意类型的数组拼接成字符串;
public static void sort(参数也是任意类型的);//对数组进行排序,底层用的是快速排序方法;
public static int binarySeach(数组名);//二分查找,前提是数组要有序
7、进制转换:
十进制转换为其他进制:public static String toString(int n,int radix)
其它进制转换为十进制:public static int parseInt(String s,int radix)
8、只要是对象,就要先判断是不是null,否则会造成空指针异常(NullPointerException)
9、注意:
Integer的直接赋值:如果-128~127之间,会直接从缓冲池里获取数据
10、判断某个字符是不是数字?大写字母?小写字母?
public static boolean isDigit(int codePoint);
public static boolean isLowerCase(char ch);
public static boolean isUpperCase(char ch);
11、正则表达式的规则:\ 的作用就是取消转义作用
A:字符
x 字符x。举例:‘a’就表示字符a
\\反斜线字符
\n 换行符
\r 回车符
B:字符类
[abc] a、b或者c
[^abc] 任何字符,除了a、b或者c
[a-zA-Z] a到z或者A到Z,两头的字母包括在内(范围)
[0-9] 0到9的字符都包括
C:预定义字符:
. 表示任意字符。如果就是表示一个.的话,用\\.
\d 数字[0-9]
\w 单词字符[a-zA-Z_0-9]
在正则表达式里面组成单词的东西必须由这些东西组成;
D:边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界:就是不是单词字符的地方
E: Greedy数量词
X? X 一次或一次也没有
X* X 零次或多次
X+ X 一次或多次
X{n} X 恰好n次
X{n,} X 至少n次
X{n,m} X 至少n次,但不超过m次
12、利用正则表达式来制定规则,进行某些判断是非常方便的;
主要的几个功能:
public boolean matches(String regex) //来判断某字符串是否符合正则表达式的要求
例如:邮箱的格式问题、手机号码的格式问题等。
public String[] split(String regex,int limit) //分割功能,按要求进行分割
例如:要分割一个年龄段:18-20,分割的要求就是“-”,这样就能得到18和20这两个字符。
public String replaceAll(String regex,String replacement)
//使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串
//下面是查找功能:(查阅API)查找符合规则的字符串等。
典型的调用顺序是 :
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
13、Random():产生随机数的类
构造方法:
public Random();//没有给种子,用的是默认种子,是当前时间的毫秒值;
public Random(long seed);//给出指定的种子,给定种子后,每次产生的随机数是固定的;
14、System的几个方法:
public static void exit(int status);//终止当前正在运行的java虚拟机,参数用作状态码,
通常非0表示异常终止。
public static long currentTimeMillis();//返回以毫秒为单位的当前时间;
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);
//从指定数组的指定位置向目标数组的指定位置复制过去相应长度,被复制的部分会被掩盖掉;
15、BigInterger能表示比Integer更大的数据。
构造方法:public BigInteger(String value);
例如:BigInterger bi=new BigInteger("1254545454545454545");
当然BigInteger还有加减乘除方法,具体用的时候再查API。
public BigInteger add(BigInger val);加
public BigInteger subtract(BigInger val);减
public BigInteger multiply(BigInger val);乘
public BigInteger divide(BigInger val);除
public BigInteger[] divideAndRemainder(BigInger val);//返回商和余数的数组
16、Collection接口是层次结构中的根接口:当然要想用接口中的这些方法,还是要通过实现这个接口的类来实现。
1)、添加功能:
boolean add(Object obj):添加一个元素
boolean addAll(Collection c):添加一个集合的元素
2)、删除功能:
void clear():删除所有元素
boolean remove(Object o):移除指定的元素
boolean removeAll(Collection c):移除一个集合的元素
3)、判断功能:
boolean contains(Object o):判断是否包含指定的元素
boolean containsAll(Collection c):判断是否包含指定的集合元素(包含其中的一个还是所有?)
boolean isEmpty():判断集合是否为空
4)、获取功能:
Iterator<E> iterator():重点
迭代器,这个是集合的专用遍历方式;
Iterator it=c.iterator();
//先判断是否有下一个元素,在输出下一个元素
if(it.hasNext()){
System.out.println(it.next());
}
5)、长度功能:
int size():集合中的元素个数
6)、交集功能:
boolean retainAll(Collection c):移除不包含在指定集合中的所有元素(那返回值又是啥意思?)
这里的返回值的意思就是:如果有两个集合A和B,先让A和B做交集,把结果放到A中,如果集合A最终发生了
改变,就返回true,否则就返回false;
7)、把集合转换为数组:
Object[] toArray():由于集合中的元素类型可能多种多样,因此要用Object接收;
17、List集合是有序的可重复的集合。(添加和输出的顺序是一致的)
List集合的特有功能:
1)、添加功能:
void add(int index,Object element):在指定位置添加元素(在添加元素的时候,必须要按照索引
依次添加,否则会报错。也就是说必须先添加索引为0的元素,再添加索引为1的元素,依次类推)
2)、获取功能:
Object get(int index):获取指定位置的元素
3)、列表迭代器:
ListIterator listIterator():List集合特有的迭代器
4)、删除功能:
Object remove(int index):根据索引删除元素,返回被删除的元素
5)、修改功能:
Object set(int index, E element):根据索引修改元素,返回被修改的元素
6)、ListIterator是列表迭代器,它继承Iterator这个接口,那么Iterator有的方法,它也有,像是
hasNext()、Next()、remove(),但是ListIterator可以向前面拿元素,有个方法叫previous(),它
可以取前一个元素,就类似于next()方法,自不过是顺序反着来的。
ListIterator可以实现逆向遍历元素,但是逆向遍历的前提是先正向遍历元素,因此,这个方法一般
不怎么实用。
18、ListIterator这个列表迭代器:
当我们通过迭代器对集合进行遍历的时候,如果我们通过集合的方法向集合添加了元素,而此时迭代器
并不知道,所以就报错了,这个错叫并发修改异常。其实改正的方法很简单:1、你可以通过迭代器向
集合中添加元素;2、你可以用集合进行遍历,而不通过迭代器。
19、List的几个实现类:(具体的小区别,可以查阅API)
ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高
Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低
LinkedList:
底层数据是链表,查询慢,增删快。
线程不安全,效率高
LinkedList的特有功能:
public E getLast()
public E getLast()
public E removeFirst()
public E removeLast()
20、无论是Iterator还是ListIterator都是为集合服务的,它们是用来遍历集合的一个工具。
21、泛型:是一种把类型明确工作推迟到创建对象或则调用方法的时候采取明确的特殊类型。
格式: <数据类型> 此处的数据类型只能是引用类型。
好处:
把运行期间的问题提前到了编译期间;
避免了强制类型转换;
优化了程序设计,解决了黄色警告线;
22、泛型类:把类型定义到类上;
public Demo<T>{}
泛型方法:把类型定义到方法上;
public <T> void show(){}
泛型接口:把类型定义到接口上;
public interface IMusic<泛型类型1,.....>{
public abstract void mp3();
}
23、增强for:for循环的一种
for(元素数据类型 变量:数组或者Collection集合){
使用变量即可,该变量就是元素
}
好处:简化了数组和集合的遍历;
弊端:增强for的目标不能是NUll;
解决办法就是在遍历之前先判断一下集合是否为null;
其实增强for就是用来替代迭代器的;
24、静态导入:
就是直接将静态类中的方法导入到.java 文件中,例如:Math.abs(-89);这个方法:
在最前面你可以写上:import java.lang.Math.abs;
而你在用的时候可以直接写:abs(-89);
这种静态导入的格式:import static 包名.类名.方法名
不过这个方式根本不实用。
25、可变参数:如果在一个方法中你不确定有多少个参数,只有到调用方法的时候才会确定,那怎么写一个可以根据你输入参数的多少来计算的方法呢???
用可变参数的方法:
格式:修饰符 返回值 方法名(参数类型... 变量名)
26、public static <T> List<T> asList(T... a)//把一个数组转换为一个集合
注意:这里将一个数组转换为一个集合,那么这个集合的本质还是一个数组,也就是说这个“集合”的长度是固定的
,不能用add(),remove(int index)等方法。
当然还有一个放法可以将一个集合转换为数组:toArray();
27、Collection
|---List
有序--存储和取出一致,可重复
|--Set
无序--存储和取出不一致,唯一
instenceof ?????
obj instenceof Student????
Comparable类????用在TreeSet中,比较的时候。
A? B : C----------这是什么表达式?????
为什么每次键盘录入的时侯都会有黄色警告线???Scanner s=new Scanner(System.in);//好像显示s没有关闭。
28、HashSet来存储引用类型的时候,在底层实际调用的是HashCode()方法和equals()方法。那么之所以HashSet
存储的数据是没有重复的,是因为它在调用add()方法的时候,先比较要添加对象的哈希值,然后再比较这个
对象里实际存储的值。但是,如果是同一个Student类型的对象s1("王祖贤",28),s2("王祖贤",28)很显然它们
的哈希值肯定不一样,但是他们这两个对象里存储的值是一样的,在我们看来,这两个对象是一样的,因此,
我们希望在添加对象的时候,只添加一个,这个时候,我们需要重写hashCode()方法和equals()方法。此时,
我们要想法让hashSet在调用add方法的时候,这两个方法,都能执行。具体做法就是:alt+shift+s +鼠标点击出
重写hashCode()和equals()方法.
29、LinkedHashSet继承与HashSet,它的底层是哈希表和链表:这就保证了:唯一、有序(和HashSet有区别哟)
TreeSet:也是有序且唯一,但是这个顺序是可以排序的。TreeSet的底层是二叉树,并且是一个平衡二叉树。
将对象进行排序,要指明按照什么排序。
TreeSet:(排序----①自然排序、②比较器排序)
TreeSet在添加元素的时候,要确保唯一,也就是不重复,就要拿要添加的元素和集合中原有的元素进行比较,
然而,真正的比较是依赖于元素的compareTo()方法的,而这个方法是在Comparable里面,所以,你要想重写
该方法,就必须先实现该接口.这个接口表示的就是自然排序。
TreeSet集合保证元素排序和唯一性的原理:
唯一性:是根据比较的返回值是否是是0来决定。
排序:
A:自然排序:(元素具备比较性)
让元素所属的类实现自然排序接口Comparable
B:比较器排序:(集合具备比较性)
让集合的构造方法接收一个实现比较器接口(Comparator)的子类对象
30、Map接口,主要学习它的实现类HashMap和TreeMap。
添加(修改)功能:
V put(K key,V value)//如果键是第一次添加,就直接把要添加的元素添加进去,返回NUll;
如果键不是第一次添加,就把当前的值替换掉之前的值,返回之前的值.
删除功能:
void clear()//清除所有元素,或者说是清除所有映射;
V remove(Object key)//按照键来删除,返回被删除的键的值,如果要删除的键不存在,就返回NUll.
判断功能:
boolean containsKey(Object key)//判断是否包含指定的键
boolean containsValue(Object value)//判断是否包含指定的值
boolean isEmpty()//判断这个集合是否为空
获取功能:
Set<Map.Entry<K,V>> entrySet()//???
V get(Object key)//返回指定键对应的值
Set<K> keySet()//返回该集合中所有键的集合
Collection<V> values()//返回该集合中所有值的集合
长度功能:
int size()//得到集合的长度
-----------------------------------------------------------------------------------
1、Map接口的实现类主要学习:HashMap和TreeMap
LinledHashMap是HashMap的子类,又叫链表式哈希Map,HashMap保证了元素的唯一性,链表保证了元素的有序
性(存储和取出有序)
TreeMap是基于红黑树的Map接口的实现。
TreeSet和TreeMap都可以默认用自然排序,当然也可以自己写一个比较器(记得实现Comparator接口),进行排序。
2、Hashtable和HashMap的区别:
Hashtable:线程安全,效率低。不允许null键和null值
HashMap:线程不安全,效率高。允许null键和null值
3、Collections和Collection的区别:
Colletions是一个类:是针对集合操作的工具类,有对集合进行排序和二分查找的静态方法;
Colletion是一个顶层接口,有子接口List和Set。
Collections的几个基础方法:
public static void reverse(List<?> list)//反转
public static void shuffle(List<?> list)//随机置换集合中的元素位置
public static <T extends Comparable<? super T>> void sort(List<T> list)
//排序,默认是自然排序,当然也可以自己写个比较器,来排序。
--------------------------------------------------------------------------------------------------------------------------

浙公网安备 33010602011771号