原本笔记都是手写的,为了之后方便保存和查阅,还是下定决心,把他敲出来正好作为一篇博客的内容。也借这个机会,好好的复习一遍Java基础知识。这是上半部分。
自学材料:黑马程序员Java全套视频
位(bit):一个数字0或1
字节(byte):8位一字节,这是数据存储中的最小单位
1Byte = 8bit
1KB = 1024Byte
Java程序运行时的环境,包含 JVM 和 核心类库
JDK(Java Development Kit)Java程序开发工具包, 包含 JRE 和 开发人员使用的工具
想要运行一个Java程序,只需要安装JRE;想要开发一个Java程序,必须安装JDK
结构:
JDK 编译等开发工具JRE 运行类库JVM指在程序中,我们自己定义的内容。比如类的名字、方法的名字和变量的名字等等
命名规范:
1)类名规范:
首字母大写,后面的每个单词的首字母大写(大驼峰式)
2)变量名规范:
首字母小写,后面每个单词首字母大写(小驼峰式)
3)方法名规范:
同变量名
字符串常量:凡是用双引号引起来的部分。“abc”
字符常量:只是用单引号引起来的单个字符。‘A’
整数:byte short int long
浮点:double float
字符:char
布尔:boolean
byte、short、char这三种类型在运算的时候,都会被首先提升为int类型,然后再计算
‘0’ :48
‘A’ :65
‘a’ :97
一旦运算当中有不同数据类型的数据,那么结果将会是数据类型范围大的那种
对于 ++ 和 –前++:那么变量立刻马上+1,然后拿着结果进行使用后++:那么首先使用变量本来的数值,然后再让变量+1–类型 类似与&&和||
如果根据左边可以判断得到最终结果,那么右边的代码将不执行
格式:
数据类型 变量名称 = 条件判断 ? 表达式A True :表达式B False
注意事项:
必须同时保证表达式A和表达式B都符合左侧的数据类型的要求三元运算符的结果必须被使用数据类型[] 数组名称 = new 数据类型[长度]
静态初始化数组的格式:数据类型[] 数组名称 = new 数据类型[] {元素1,元素2,。。。}
数据类型[] 数组名称 = {元素1,元素2,。。。}
使用动态初始化数组的时候,元素会被自动拥有一个默认值
整数类型 0浮点 0.0字符 ‘\u0000’布尔 false引用 null1)栈
存放的都是方法种的局部变量。方法的运行一定要在栈中运行
作用域:一旦超过作用域,立刻从栈内存中消失
2)堆(Heap)
凡是new出来的东西,都在堆中
堆内存中的东西都有一个地址值:16进制
3)方法区(Method Area)
存储 .class 的相关信息,包含方法的信息
4)本地方法栈
5)寄存器
例如以下分析:
面向对象的三大特性:封装、继承、多态
定义类时,成员方法不要static关键字
创建类,格式: 类名称 对象名 = new 类名称( )
当方法的局部变量和类的成员变量重名时,根据”就近原则“,优先使用局部变量
如果在方法中需要访问本类中的成员变量,使用的格式:this.成员变量名
格式:
public 类名称 (参数类型 参数名称,。。。){方法体}
注意:
如果没有编写任何的构造方法,编译器会默认给一个构造方法构造方法是可以进行重载的Scanner sc = new Scanner(System.in)
使用1)获取键盘输入的一个int数字
int num = sc.nextInt();
2)获取键盘输入的一个字符串
String str = sc.next();
只有右边的对象,没有左边的名字和赋值运算符
形如:
new Person().name = “xxx”;
new Person().showName();
注意:
匿名对象只能使用唯一的一次,下次再用不得不在创建一个新的对象用来生成随机的数字
创建Random r = new Random();
使用1)获取一个随机int数字(范围是int 的所有范围,有正负两种):
int num = r.nextInt();
2)获取一个随机的int数字(参数代表了范围,左闭右开区间):
int num = r.nextInt(3); // 表示[0,3),也就是0到2
也就是装在集合中的所有元素,全都是统一的什么类型
注意:泛型只能是引用类型,不能是基本类型
从JDK1.7开始,创建ArrayList时的右侧尖括号<> 内不用写泛型
常用方法:
1)添加数据:.add()
2)获取数据,参数是索引:.get(int index)
3)删除元素,参数是索引号,并返回对应位置的元素:.remove(int index)
4)获取集合的长度:.size()
注意:
如果希望向集合ArrayList当中存储基本类型数据,必须使用基本类型的包装类
基本类型 包装类(引用类型,包装类都位于java.Lang包下)
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
注意:
从JDK1.5开始,支持自动装箱/拆箱
字符串效果上相当于char[]字符数组,但是底层原理是Byte[]字节数组
创建字符串的常见3+1种方式 三种构造方法 public String()public String(char[] array):根据字符数组的内容,创建字符串public String(byte[] array):根据字节数组的内容,创建 直接创建:String str = “Hello”;对于基本数据类型来说:”==“ 是进行数值的比较
对于引用类型来说:”==“是进行地址值的比较
String类的常用方法
1)比较字符串的内容是否相同(两种)
.equals(…)注意:如果比较双方一个常量,一个变量,推荐把常量字符串写在前面,防止空指针异常。
.equalsIgnoreCase(…):忽略大小写进行比较2)字符串操作的方法
.length():字符串的长度.concat(String str):拼接字符串,返回新的字符串public char charAt(int index):获取指定索引位置的单个字符(索引从0开始)public int indexOf(String str):找到参数字符串在本字符串中首次出现的索引位置,如果没有返回-1值3)字符串的截取方法
.substring(int index):截取从参数位置到字符串末尾,返回新字符串.substring(int begin,int end):截取从begin开始,到end结束。注意:[begin,end):包含左边,不包含右边4)字符串转换的方法
.toCharArray():转化为字符数组,返回.getBytes():获取当前字符串底层的字符数组public String replace(CharSequence oldString, CharSequence newString):将字符串中的老字符串替换为新的字符串,返回5)分割字符串
public String[] split(String regex):根据regex,将字符串切分成若干个部分regex:是正则表达式用了Static关键字以后,里面的内容不再属于对象自己,而是属于类的,所以凡是本类的对象,都共享同一份
一旦使用static修饰成员方法,那么这就成为了静态方法。静态方法不属于对象,而是属于类对于静态方法来说,最好通过类名称来调用;而且不需要创建对象就可以直接通过类名称来调用总结:无论是成员变量,还是成员方法,如果有了static,都推荐使用类名称进行调用
例如:
类名称.静态变量
类名称.静态方法()
注意:
静态不能访问非静态静态方法中不能用this格式:
public class 类名称{
static{//静态代码块的内容}
}
特点:
当第一次用到本类的时候,静态代码块执行唯一的一次静态内容总是优先于非静态,所以静态代码块比构造方法还要先执行静态代码块的典序用途:
用来一次性的对静态成员变量进行赋值与数组相关的工具类
1)public static String toString(…):将数组变成字符串
使用:Arrays.toString(…)
2)public static void sort(…):对数组元素进行排序
注意:
如果是数组数组,默认升序,从小到大如果是字符串,按照字母升序如果是自定义类型,那么自定义的类需要有Comparable或Comparator接口的支持与数学运算有关
Math.abs(double num)Math.ceil(double num):向上取整Math.floor(double num):向下取整Math.round(double num):四舍五入Math.PI:近似圆周率常量如果没有继承,就没有多态
继承主要解决的问题就是:共性抽取
注意:
1)方法的覆盖重写的特点:创建的是子类对象,则优先用子类的方法
2)子类方法的返回值必须小于等于父类方法的返回值范围
3)子类方法的权限必须大于等于父类方法的权限修饰符
public > protected > (default) > private
1)子类构造方法中有一个默认隐含的”super()“调用,所以一定是先调用父类的构造,后执行子类的构造
2)子类的构造可以通过super关键字来调用父类的重载构造
3)super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super()
总结:
子类必须调用父类构造方法,不写则赠送super();写了则用写的指定的super()调用。super()只能有一个,还必须是第一个
super关键字的三种用法:
在子类的成员方法中,访问父类的成员变量在子类的成员方法中,访问父类的成员方法在子类的构造方法中,访问父类的构造方法this关键字的三种用法:
在本类的成员方法中,访问本类的成员变量在本类的成员方法中,访问本类的另一个成员方法在本类的构造方法中,访问本类的另一个构造方法注意:
1)this(…)调用也必须是构造方法的第一个语句,唯一一个
2)super和this两种构造调用,不能同时使用
1)
抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束
抽象类:抽象方法所在类,必须是抽象才行。在class之前写上abstract即可
2)如何使用抽象类和抽象方法
不能直接创建new抽象类对象必须先用一个子类来继承抽象父类,子类必须重写抽象父类中的抽象方法创建子类对象进行使用3)抽象类使用的注意事项
抽象类不能创建对象,只能创建其非抽象子类的对象抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用抽象类中,不一定含有抽象方法,但是有抽象方法的类必定是抽象方法抽象类的子类,必须重写抽象父类的所有的抽象方法,除非该子类也是抽象类就是多个类的公共规范
1)
Java7,接口包含:1.常量、2.抽象方法
Java8,额外包含:3.默认方法、4.静态方法
Java9,额外包含:5.私有方法
2)定义抽象方法
格式:
public abstract 返回值类型 方法名(参数列表);
注意:
接口中的抽象方法,修饰符必须是两个固定的关键字:public abstract这两个关键字修饰符,可以选择性的省略3)实现类必须重写接口中所有的抽象方法,除非实现类是抽象类
用来解决接口升级的问题
格式:
public default 返回值类型 方法名称(参数列表){方法体}
注意:
接口的默认方法,可以通过接口的实现类的对象,直接调用接口的默认方法,也可以被接口的实现类进行覆盖重写格式:
public static 返回值类型 方法名称(参数列表){方法体}
用法:通过接口名称,直接调用其中的静态方法;格式:接口名称.静态方法名(参数);
只有接口自己才能调用,不能被实现类或别人调用
1)普通私有方法,解决多个默认方法之间的重复代码问题
格式:
private 返回值类型 方法名称(参数列表){方法体}
2)静态私有方法,解决多个静态方法之间重复代码问题
格式:
private static 返回值类型 方法名称(参数列表){方法体}
必须使用 public static final 三个关键字进行修饰
格式:public static final 数据类型 常量名称 = 数据值;
注意:
接口中的常量,可以省略public static final关键字接口中的常量,必须进行赋值,不能不赋值,一旦赋值就不能gaib接口中的常量的命名规则:使用完全大写的字母,用下划线进行分割1)接口是没有静态代码块或者构造方法的
2)一个类的直接父类是唯一的;但是一个类可以同时实现多个接口
3)如果实现类所实现的多个接口中,存在重复的默认方法,那么实现类必须对冲突的默认方法进行重写
4)一个类如果直接父类中的方法和接口中的默认方法产生冲突时,优先用父类中的方法
接口与接口之间可以是多继承
例如:public interface A extends B,C{…}
注意:
多个父接口中的默认方法如果重复,那么子接口必须进行默认方法的重写,而且要带着default关键字1)
一个对象拥有多种形态,就是对象的多态性
即,【左侧】父类引用 指向【右侧】子类对象
格式:
父类名称 对象名 = new 子类名称(); 或者: 接口名称 对象名 = new 实现类名称();
2)多态情况下访问成员变量有两种方式:
直接通过对象访问成员变量:等号左边是谁,优先用谁,没有则向上找间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找3)多态情况下,成员方法的访问规则:
看new的是谁,就优先用谁,没有则向上找格式:同多态的写法
含义:右侧创建的一个子类对象,把它当作父类来看待使用
注意事项:向上转型一定是安全的,从小范围转向大范围
弊端:对象一旦向上转型为父类,那么就无法调用子类原本特有的内容
解决方案:用对象的向下转型还原
格式:子类名称 对象名 = (子类名称) 父类对象;
注意:向下转型的前提是保证对象本来创建的时候,就是这个子类的
格式:对象 instanceof 类名称
返回的是布尔值
常见的四种用法
1)当final关键字用来修饰一个类的时候
public final class 类名称{。。。}
含义:当前这个类不能有任何的子类(太监类);所有的成员方法都无法进行覆盖重写(因为没有子类)
2)当final关键字用来修饰一个方法时
这个方法就是最终方法,不能被覆盖重写
注意:对于类、方法来说,abstract关键字和final关键字不能同时使用,因为矛盾
3)当final用来修饰 局部变量,那么这个变量就不能进行更改
不变的含义:
基本数据类型,变量中的数据不变引用类型,变量的地址值不可改变,但是内容可以改变4)当final用来修饰 成员变量,这个变量也是不可变
成员变量必须手动赋值,不能再给默认值了对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一必须保证类中的所有构造方法都会对final的成员变量进行赋值一个类内部包含另一个类
分类:
成员内部类局部内部类(包含匿名内部类)定义格式:
外部类{
内部类{…}
}
注意:内用外,随意访问;外用内,需要内部类对象
1)使用成员内部类,有两种方式:
间接方式:在外部类的方法中,使用内部类,然后调用外部类的方法直接方式,公式:外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
2)内部类的重名变量访问
局部变量: num
内部类的成员变量: this.num
外部类的成员变量: 外部类名称.this.外部类成员变量名
如果一个类是定义在一个方法内部的,那么这就是一个局部内部类
”局部“:只有当前所属方法才能使用它,出了这个方法外面就不能使用了
格式:
外部类{
外部类方法{
局部内部类{…}
}
}
局部内部类,如果希望访问所在的方法的局部变量,那么这个局部变量必须是【有效final的】
如果接口的实现类或父类的子类,只需要使用唯一一次,那么这种情况下就可以省略该类的定义,而改为使用匿名内部类。创建对象和调用方法的时候只能使用一次
匿名内部类的定义格式:
接口名称 对象名 = new 接口名称(){ //覆盖重写所有的抽象方法 }
1)知识点
时间原点(0毫秒):英国格林威治的 1970年1月1日00:00:00;中国属于东八区,所以会加上8小时System.currentTimeMills():获取当前系统时间到时间原点的距离1天 = 24*60*60 = 86400秒 = 86400 000毫秒2)Date类的构造方法
空参构造:Date()获取当前系统的日期和时间
带参构造:Date(long date)参数:毫秒值;把毫秒值转化为Date日期
3).getTime() 方法
把日期转化为毫秒值;相当于System.currentTimeMills()
作用:
格式化(日期 -> 文本)解析(文本 -> 日期)成员方法:
String format(Date date)Date parse(String source)DateFormat类是抽象类,无法直接创建对象使用,用DateFormat的子类java.text.SimpleDateFormat
构造方法:SimpleDateFormat(String pattern)
参数pattern:传递指定的模式
y 年;M 月;d 日;H 时;m 分;s 秒
例如:”yyyy-MM-dd HH:mm:ss“
注意:模式中的字母不能改变,连接模式的符号可以改变
new SimpleDateFormat(“yyyy-MM-dd”).format(new Date())
把文本解析为日期,例如:new SimpleDateFormat(“yyyy-MM-dd”).parse(“2020-10-10”)
其中,如果字符串和构造方法的模式不一样,就会抛出ParseException异常
1)public static long currentTimeMills()
返回以毫秒为单位的当前时间
2)public static void arraycopy(参数1,2,3,4,5)
静态方法,将数组中指定的数据拷贝到另一个数组中
参数:
src:源数组srcpos:源数组中的起始位置(索引)dest:目标数组destpos:目标数组中的起始位置length:要复制的数组元素的数量1)String类
字符串是常量,在创建之后不能改变
字符串底层是被final修饰的数组(private final byte[] value),不能改变,是一个常量
2)StringBuiler类:字符串缓冲区
可以提高字符串的操作效率。底层也是一个数组,但是没有被final修饰,可以改变长度。
初始容量为16(byte[] value = new byte[16])。如果超出容量,会自动扩容
3)构造方法:
StringBuilder()StringBuilder(String str)4)常用方法:
public StringBuilder append(…);添加任意类型数据的字符串形式,并返回
public String toString()把当前的StringBuilder对象转换为String对象
1)基类 + ”“
例如:int i1 = 100; String s1 = i1 + “”;
2)包装类中的静态方法toString
static String toString(int i)
例如:Integer.toString(100);
3)String类的静态方法valueOf
static String valueOf(int i)
例如:String.valueOf(100);
String -> 基本数据类型使用包装类的静态方法parseXxx("…")
例如:Integer类:static int parseInt(String s)
所有单列集合最顶层的接口,里面定义了所有单列集合的共性方法(7个)
1)public boolean add(E e):添加元素到集合中
2)public boolean remove(E e):把给定的对象在当前的集合中删除
3)public boolean contains(E e):判断集合中是否包含给定的对象
4)public boolean isEmpty():判断当前集合是否为空
5)public int size():返回集合中元素的个数
6)public Object[] toArray():把集合中的元素,存储到数组中
7)public void clear():清空集合中所有的元素,但是不删除集合,集合还存在
(对集合进行遍历)
接口中有两个常用的方法:
boolean hasNext():判断集合中还有没有下一个元素,有就返回true,没有就返回falseE next():返回集合中的下一个元素;把指针向后移动一位迭代器的使用步骤:
1)使用集合中的方法 .iterator() 获取迭代器的实现对象,使用Iterator接口来接收(多态);并且把指针(索引)指向集合的 -1 索引处
例如: Iterator< E > it = 集合名.iterator(); //其中,集合是什么泛型,迭代器是什么泛型
2)使用迭代器中的 .hasNext() 方法,判断有没有下一个元素
3)使用迭代器中的 .next() 方法 取出集合的下一个元素;并将指针向后移动一位
专门用来遍历数组和集合。
内部原理是个iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
1)创建集合对象,不使用泛型:
好处:集合不使用泛型,默认类型就是Object类型,可以存储任意类型的数据弊端:不安全,会引发异常2)创建集合对象,使用泛型
好处: 避免了类型转换的麻烦,存储的是什么类型,取出就是什么类型把运行期间的异常(代码运行之后抛出的异常),提升到了编译器(写代码的时候报错) 弊端:泛型是什么类型,只能存储什么类型的数据1)类
例如:
public class 类名 < E > {
private E name;
…
}
2)方法
泛型的定义在方法的修饰符和返回值类型之间
格式:
public <泛型> 返回值类型 方法名(参数列表){…}
例如:
public class …{
public < M > void method (M m){
…(m);
}
}
3)接口
两种使用方式:
在一个实现类实现一个接口的时候,指定泛型创建对象的时候才确定泛型的类型代表任意的数据类型
1)使用方式:
不能在创建对象的时候使用只能作为方法的参数,传递数据类型时使用2)通配符高级使用:受限泛型
泛型上限:< ? extends 类 >只能接收该类及其子类
泛型下限:< ? super 类 >只能接收该类及其父类
使用默认的随机源使得集合中的元素随机化
例如:Collections.shuffle(集合);
list接口中几个Collection中没有,list中特有的方法
1)public void add(int index, E element):将指定的元素添加到该集合中的指定位置上
2)remove(int index):删除指定元素,并返回被移除的元素内容
3)public E set(int index, E element):用指定的元素替换集合中指定位置的元素,并返回被替换的元素值
4)get(int index)
遍历集合的3种方法:
普通for循环使用迭代器增强for循环增删元素,也是创建新的数组,所以也是查询快,增删慢
查询慢,增删快
里面包含了大量操作首尾元素的方法(特有的方法)
注意:在使用LinkedList集合的特有的方法,不能使用多态
1)添加元素
public void addFirst(E e):插入列表开头public void addLast(E e)public void push(E e):插入到列表所表示的堆栈;等效于 .addFirst()2)获取元素
public E getFirst()public E getLast()注意:如果使用.clear()清空了集合中的元素时,使用上述两个方法,会抛出异常
3)删除元素
public E removeFirst():删除并返回第一个元素public E removeLast()public E pop():从列表表示的堆栈中弹出第一个元素;等效于 .removeFirst()4)判断是否为空
public boolean isEmpty():不含元素,返回true这里面的方法和Collection接口里面的差不多一致
特点:
1)Set接口有的所有特点
2)是一个无序的集合,存储和取出元素的顺序可能不一样
3)底层是一个哈希表结构(查询的速度非常快)
遍历方式:
使用迭代器使用增强for循环注意:
HashSet存储的自定义类型元素类中,必须重写hashCode和equals方法
1)Java里的哈希值,是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个模拟出来的逻辑地址,而不是实际存储的物理地址)
2)在Object类中有一个获取对象哈希值的方法
int hashCode():返回对象的哈希值
hashCode方法的源码:public native int hashCode()
其中,native:代表该方法调用的是本地操作系统的方法
注意:
之前对象的地址值(toString)输出的,就是hashCode地址值String类重写了Object类的hashCode方法3)哈希表结构
JDK1.8版本之前:哈希表 = 数组 + 链表JDK1.8版本之后:哈希表 = 数组 + 链表 ;哈希表 = 数组 + 红黑树两种混合使用。当链表的长度超过了8位时,就会把链表转化为红黑树,来提高查询的速度
Set集合在调用add方法的时候,add方法会调用元素的hashCode方法和equals方法,判断元素是否重复
前提:存储的元素必须重写hashCode方法和equals方法
1)先调用hashCode方法计算元素hash值
若没有hash冲突,就存入若有hash冲突,就进行 2)2)调用equals方法比较哈希值相同的元素
特点:
底层是:哈希表(数组+链表/红黑树)+链表。多了一个链表,用来记录元素的存储顺序,保证元素的有序前提:当方法的参数列表里的数据类型已经确定,但是参数的个数不确定,就可以使用可变参数
使用格式:在定义方法时使用
修饰符 返回数据类型 方法名(数据类型 … 变量名){。。。}
可变参数的底层原理底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数
注意:
一个方法的参数列表,只能有一个可变参数如果方法的参数有多个,那么可变参数必须写在参数列表的末尾可变参数的特殊(终极)写法
public static void method(Object … obj){…}
这种可以接收任意数据类型参数
用来对集合进行一些操作
1)public static < T > boolean addAll(集合,元素,,,):往集合中添加一些元素
2)public static void shuffle(list< ? > list):打乱集合顺序
3)public static < T > void sort(list< T > list):将集合中元素按照默认规则排序
注意:sort使用的前提时被排序的集合里的存储的元素必须:
实现Comparable接口并重写接口中的compareTo方法来定义排序规则
public class Person implents Comparable<Person>{ @Override public int compareTo(person o){ //升序 //return this - o //降序 return o - this } }Comparable接口的排序规则:
自己(this)- 参数 :升序参数 - 自己(this):降序4)public static < T > void sort(list< T > list, Comparator< ? super T >):将集合中的元素按照指定规则进行排序
Collections.sort(list,new Comparator<Integer>{ //重写比较规则 @Override public int compare(Integer o1,Integer o2){ return o1 - o2;//升序 } });Comparator的排序规则:
o1 - o2 :升序可以多写几个规划,组合排序Map集合的特点:
1)Map集合是一个双列集合,一个元素包含两个值:一个key,一个value
2)key和value的数据类型可以相同,也可以不同
3)key是不允许重复的,value可以重复
4)key和value时一一对应的
Map接口中的常用方法:
1)public V put(K key,V value):把指定的键和指定的值添加到map集合中
返回值:
存储键值对的时候,key不重复,返回值为null存储键值对的时候,key重复,会使用新的value替换map中重复key的value,返回被替换的value值2)public V remove(Object key)
返回值:
返回被删除元素的value值key不存在时,返回null3)public V get(Object key)
返回值:
key存在时,返回对应的value值key不存在时,返回null4)boolean containsKey(Object key)
判断集合中是否包含指定的键,包含返回true,不包含返回false
1)用Set< k > keySet()方法,把Map集合中的所有key取出来存储到Set集合中
2)使用迭代器或增强for循环,遍历Set集合,获取Map集合的每一个key
3)用 .get(key) 方法,获取所有value
Map.Entry< k,v >:在接口Map中有一个内部接口Entry
作用:当Map集合一创建,那么就会在Map集合中创建一个Entry对象,用来记录键与值,即键值对对象/键与值的映射关系
步骤:
1)方法:Set<Map.Entry<k,v>> entrySet():把Map集合内部的多个Entry对象取出来存储的一个Set集合中
2)遍历Set集合,获取Set集合中的每一个Entry对象
3)应用Entry对象中的方法:
getKey():获取key
getValue():获取value
例如:
public static void main(String[] args) { //创建Map集合对象 Map<String,Integer> map = new HashMap<>(); map.put("赵丽颖",168); map.put("杨颖",165); map.put("林志玲",178); //1.使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中 Set<Map.Entry<String, Integer>> set = map.entrySet(); //2.遍历Set集合,获取每一个Entry对象 //使用迭代器遍历Set集合 Iterator<Map.Entry<String, Integer>> it = set.iterator(); while(it.hasNext()){ Map.Entry<String, Integer> entry = it.next(); //3.使用Entry对象中的方法getKey()和getValue()获取键与值 String key = entry.getKey(); Integer value = entry.getValue(); System.out.println(key+"="+value); } System.out.println("-----------------------"); for(Map.Entry<String,Integer> entry:set){ //3.使用Entry对象中的方法getKey()和getValue()获取键与值 String key = entry.getKey(); Integer value = entry.getValue(); System.out.println(key+"="+value); } }HashMap的特点:
HashMap集合底层是hash表,查询速度更快是一个线程不安全的集合,是多线程集合,速度快HashMap集合是一个无序的集合,存储元素和取出元素的顺序可能不一致注意:
HashMap存储自定义类型的键值对时,要保证key值得元素是唯一的,即必须重写hashCode()方法和equals()方法
特点:
底层是哈希表+链表。可以保证迭代的顺序是一个有序的集合,存储元素和取出元素的顺序是一致的1)HashTable
底层是一个哈希表是一个线程安全的集合是单线程集合,速度慢2)HashMap
底层是一个哈希表是一个线程不安全的集合是多线程集合,速度快1)HashTable
不能存储null值和null键2)之前学过的所有集合
都可以存储null值和null键
HashTable和Vector一样,在JDK1.2之后被更先进的HashMap、ArrayList取代了
但是HashTable的子类Properties仍然在被使用
1)String类的方法toCharArray,把字符串转化为一个字符数组,在遍历
2)String类的方法length() + CharAt(索引),遍历数组
List、Set、Map接口里面添加了一个静态方法 of,可以给集合一次性添加多个元素
static < E > List< E > of (E …)
使用前提:当集合中的元素个数不再改变的时候使用
注意:
1)of方法只适用于List、Map、Set接口,不适用于接口的实现类
2)of方法的返回值是一个不能改变的集合,集合不能再使用add、put方法添加元素,会抛出异常
3)Set、Map接口在使用of方法时,不能有重复的元素,否则也会抛出异常