API基础第三天:
回顾:
- 正则表达式:匹配字符串内容是否符合格式要求
- String支持正则表达式的方法:
- matches():匹配
- replaceAll():替换
- split():拆分
- Object:是所有类的鼻祖,所有类都直接或间接继承了Object,万物皆对象,为了多态
- 两个经常被派生类重写的方法:toString()和equals()
- 输出引用变量时默认会调用Object的toString(),返回结果为类的全称@hashcode值,没有参考意义,因此常常重写toString()来返回具体的属性值。
- 调用Object的equals()时默认还是在判断==(即比较地址),没有参考意义,因此常常重写equals()来比较具体的值。
- 两个经常被派生类重写的方法:toString()和equals()
- 包装类:8种基本数据类型套了个壳
- JDK1.5时自动拆装箱特性,当编译器发现基本类型与包装类型互相赋值时,会自动补齐代码完成拆装箱过程
精华笔记:
-
什么是集合:
- 集合和数组一样,可以保存一组数据,并且提供节操作集合元素的相关方法,使用更加方便
-
java集合框架中的相关接口:
- java.util.Collection接口:是所有集合的顶级接口,封装了所有集合所共有的方法,下面有多种实现类,因此我们可以有更多的数据结构来选择。
- Collection接口下面有两种常见的子接口:-----------------------下次课详细介绍
- java.util.List:线性表,是可以重复集合,并且有序
- java.util.Set:不可重复集合,大部分实现类是无序的
-
Collection接口的常用方法:
- add():向集合中添加一个元素,成功添加则返回true
- size():返回当前集合的元素个数
- isEmpty():判断当前集合是否是空集,仅当size()为0时返回true
- clear():清空集合
- contains():判断集合是否包含给定元素
- remove():从集合中删除给定元素,成功删除则返回true
- addAll():将参数集合中的元素添加到当前集合中,添加后当前集合发生改变则返回true
- containsAll():判断当前集合中是否包含参数集合中的所有元素
- retainAll():取交集
- removeAll():删交集
-
集合的遍历:
- Collection接口提供了统一的遍历集合的方式:迭代器模式。通过iterator()方法可以获取一个用于遍历当前集合元素的迭代器(Iterator接口)。
- java.util.Iterator接口:定义了迭代器遍历集合的相关操作,不同的集合都实现了用于遍历自身元素的迭代器实现类,但是我们元素记住它们的名字,从多态的角度把它们看成Iterator即可
- 迭代器遍历遵循的步骤:问(hasNext())、取(next())、删(remove()),其中删除并不是必要操作
-
增强for循环/新循环:
-
JDK1.5时推出了一个特性:增强型for循环,也称为新循环,让我们使用相同的语法来遍历集合和数组。
-
语法:
for(元素类型 变量名 : 集合或数组){ 循环体 }
-
-
泛型:
- JDK1.5时推出了一个特性:泛型
- 泛型也称为参数化类型,允许我们在使用一个类时,传入某个类型来规定其内部的属性、方法参数或返回值类型,使得我们使用时更加方便。
- 泛型在集合中被广泛使用,用来规定集合元素的类型
- 若不指定泛型的具体类型,则默认为Object
- 若指定了泛型的具体类型,则在获取泛型的值时,编译器会做强转操作
笔记:
-
什么是集合:
- 集合和数组一样,可以保存一组数据,并且提供节操作集合元素的相关方法,使用更加方便
-
java集合框架中的相关接口:
- java.util.Collection接口:是所有集合的顶级接口,封装了所有集合所共有的方法,下面有多种实现类,因此我们可以有更多的数据结构来选择。
- Collection接口下面有两种常见的子接口:-----------------------下次课详细介绍
- java.util.List:线性表,是可以重复集合,并且有序
- java.util.Set:不可重复集合,大部分实现类是无序的
-
Collection接口的常用方法:
-
add():向集合中添加一个元素,成功添加则返回true
-
size():返回当前集合的元素个数
-
isEmpty():判断当前集合是否是空集,仅当size()为0时返回true
-
clear():清空集合
-
contains():判断集合是否包含给定元素
-
remove():从集合中删除给定元素,成功删除则返回true
package apiday03; import java.util.ArrayList; import java.util.Collection; /** * Collection集合的演示 */ public class CollectionDemo { public static void main(String[] args) { Collection c = new ArrayList(); c.add(new Point(1,2)); c.add(new Point(3,4)); c.add(new Point(5,6)); c.add(new Point(7,8)); c.add(new Point(9,0)); c.add(new Point(1,2)); //[元素1.toString(), 元素2.toString(), 元素3.toString(), ......] System.out.println(c); //[(1,2), (3,4), (5,6), (7,8), (9,0), (1,2)] Point p = new Point(1,2); /* boolean contains(Object o) 判断当前集合是否包含给定元素(o) 判断依据是给定元素是否与集合元素存在equals比较为true的情况 */ boolean contains = c.contains(p); System.out.println("是否包含:"+contains); //true /* boolean remove(Object o) ----一般都是直接调用 从当前集合中删除与给定元素equals比较为true的元素 若存在重复则只删除一次 */ c.remove(p); //认为能删除的发花,认为不能删除的发火箭 System.out.println(c); //[(3,4), (5,6), (7,8), (9,0), (1,2)] //集合中存放的是元素的引用 Collection cc = new ArrayList(); Point pp = new Point(1,2); cc.add(pp); //将pp添加到集合cc中---装的是pp的引用(地址) System.out.println("pp:"+pp); //(1,2) System.out.println("cc:"+cc); //[(1,2)] pp.setX(100); System.out.println("pp:"+pp); //(100,2) System.out.println("cc:"+cc); //[(100,2)] /* Collection c = new ArrayList(); c.add("one"); c.add("two"); c.add("three"); c.add("four"); c.add("five"); //集合重写了Object的toString()方法,返回格式如下: //[元素1.toString(), 元素2.toString(), 元素3.toString(), ......] System.out.println(c); //[one, two, three, four, five] System.out.println("size:"+c.size()); //5,输出集合的元素个数 //isEmpty()判断集合是否是空集(size()为0表示空集) System.out.println("是否是空集:"+c.isEmpty()); //false c.clear(); //清空集合 System.out.println("集合已清空"); System.out.println(c); //[] System.out.println("size:"+c.size()); //0 System.out.println("是否为空集:"+c.isEmpty()); //true */ } } -
addAll():将参数集合中的元素添加到当前集合中,添加后当前集合发生改变则返回true
-
containsAll():判断当前集合中是否包含参数集合中的所有元素
-
retainAll():取交集
-
removeAll():删交集
package apiday03; import java.util.ArrayList; import java.util.Collection; /** * 集合间操作的练习 */ public class CollectionOperDemo { public static void main(String[] args) { Collection c1 = new ArrayList(); c1.add("java"); c1.add("c++"); c1.add(".net"); System.out.println("c1:"+c1); //c1:[java, c++, .net] Collection c2 = new ArrayList(); c2.add("android"); c2.add("ios"); c2.add("java"); System.out.println("c2:"+c2); //c2:[android, ios, java] c1.addAll(c2); //将c2添加到c1中 System.out.println("c1:"+c1); //c1:[java, c++, .net, android, ios, java] System.out.println("c2:"+c2); //c2:[android, ios, java] Collection c3 = new ArrayList(); c3.add("c++"); c3.add("android"); c3.add("php"); System.out.println("c3:"+c3); //c3:[c++, android, php] boolean contains = c1.containsAll(c3); //判断c1中是否包含c3中的所有元素 System.out.println("包含所有:"+contains); //false /* //取交集,c1中仅保留c1与c3的共有元素,c3不变 c1.retainAll(c3); System.out.println("c1:"+c1); //c1:[c++, android] System.out.println("c3:"+c3); //c3:[c++, android, php] */ //删交集,将c1中与c3共有的元素删除,c3不变 c1.removeAll(c3); System.out.println("c1:"+c1); //c1:[java, .net, ios, java] System.out.println("c3:"+c3); //c3:[c++, android, php] } } -
iterator():获取迭代器-------------代码见"集合的遍历"
-
-
集合的遍历:
-
Collection接口提供了统一的遍历集合的方式:迭代器模式。通过iterator()方法可以获取一个用于遍历当前集合元素的迭代器(Iterator接口)。
-
java.util.Iterator接口:定义了迭代器遍历集合的相关操作,不同的集合都实现了用于遍历自身元素的迭代器实现类,但是我们元素记住它们的名字,从多态的角度把它们看成Iterator即可
-
迭代器遍历遵循的步骤:问(hasNext())、取(next())、删(remove()),其中删除并不是必要操作
package apiday03; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * 迭代器Iterator遍历集合的演示 */ public class IteratorDemo { public static void main(String[] args) { Collection c = new ArrayList(); c.add("one"); c.add("#"); c.add("two"); c.add("#"); c.add("three"); c.add("#"); c.add("four"); c.add("#"); c.add("five"); System.out.println(c); //[one, #, two, #, three, #, four, #, five] /* 迭代器的常用方法: 1)boolean hasNext()------------问 询问集合是否还有"下一个"元素可供迭代 注意:迭代器默认开始位置在集合第1个元素之前 无论调用多少次hasNext()方法,迭代器的位置都不会改变 2)Object next()----------------取 迭代器向后移动一个位置来指向集合的下一个元素并将其获取 */ Iterator it = c.iterator(); //获取集合c的迭代器 while(it.hasNext()){ //若有下一个元素 String str = (String)it.next(); //获取下一个元素 System.out.println(str); if("#".equals(str)){ //若str为#号 //c.remove(str); //迭代器遍历过程中不能通过集合的方法增删元素 it.remove(); //删除next()方法所获取的元素 } } System.out.println(c); } }
-
-
增强for循环/新循环:
-
JDK1.5时推出了一个特性:增强型for循环,也称为新循环,让我们使用相同的语法来遍历集合和数组。
-
语法:
for(元素类型 变量名 : 集合或数组){ 循环体 }package apiday03; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * 新循环的演示 */ public class NewForDemo { public static void main(String[] args) { String[] array = {"one","two","three","four","five"}; for(int i=0;i<array.length;i++){ System.out.println(array[i]); } //新循环遍历数组---会被编译为如上的for循环 for(String str : array){ System.out.println(str); } Collection c = new ArrayList(); c.add("one"); c.add("two"); c.add("three"); c.add("four"); c.add("five"); Iterator it = c.iterator(); while(it.hasNext()){ String str = (String)it.next(); System.out.println(str); } //新循环遍历集合---会被编译为如上的迭代器遍历 for(Object obj : c){ String str = (String)obj; System.out.println(str); } } }
-
-
泛型:
-
JDK1.5时推出了一个特性:泛型
-
泛型也称为参数化类型,允许我们在使用一个类时,传入某个类型来规定其内部的属性、方法参数或返回值类型,使得我们使用时更加方便。
- 泛型在集合中被广泛使用,用来规定集合元素的类型
- 若不指定泛型的具体类型,则默认为Object
- 若指定了泛型的具体类型,则在获取泛型的值时,编译器会做强转操作
package apiday03; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * 泛型的演示 */ public class GenericDemo { public static void main(String[] args) { Collection<Point> c = new ArrayList<>(); c.add(new Point(1,2)); c.add(new Point(3,4)); c.add(new Point(5,6)); c.add(new Point(7,8)); c.add(new Point(9,0)); //c.add("one"); //编译错误,参数类型与集合的泛型类型不匹配 Iterator<Point> it = c.iterator(); while(it.hasNext()){ Point p = it.next(); //编译器会自动补齐强转代码 System.out.println(p); } for(Point p : c){ System.out.println(p); } /* Collection<String> c = new ArrayList<>(); //泛型集合 c.add("one"); c.add("two"); c.add("three"); c.add("four"); c.add("five"); //c.add(new Point(1,2)); //编译错误,Point类型违背了集合c所指定的泛型的实际类型String //迭代器所指定的泛型类型应当与其遍历的集合的泛型一致 Iterator<String> it = c.iterator(); while(it.hasNext()){ String str = it.next(); //编译器会自动补齐强转操作 System.out.println(str); } for(String str : c){ //编译器会自动补齐强转操作 System.out.println(str); } */ } }
-
补充:
-
常见面试题:
-
JVM、JRE、JDK的区别:
- JVM:java虚拟机,是java实现跨平台的最核心部分,能够运行java语言所开发的程
- JRE:java运行环境,是运行java程序所必须的环境的集合,包括JVM+java系统类库
- JDK:java开发工具包,是java的核心,包括JRE+编译、运行等命令工具
-
java的8种基本数据类型是什么?(简述java的8种基本数据类型)
- byte:字节型,用于存储整数的,占用1个字节,范围-128到127
- short:短整型,用于存储整数的,占用2个字节,范围-32768到32767
- int:最常用的整型,用于存储整数的,占用4个字节,范围-2^31到2^31-1
- long:长整型,用于存储较大的整数,占用8个字节,范围-2^63到2^63-1
- float:单精度浮点数,用于存储小数的,占用4个字节,不能表示精确的值
- double:双精度浮点数,最常用的存储小数的类型,占用8个字节,不能表示精确的数
- boolean:布尔型,存储true或false,占用1个字节
- char:字符型,采用Unicode字符编码格式,存储单个字符,占用2个字节
-
switch可以作用于哪些数据类型上?
- 答: byte,short,int,char,String,枚举,其余类型都不允许
-
重写(override)与重载(overload)的区别:
- 重写:发生在父子类中,方法名相同,参数列表相同
- 用于在子类中修改父类中的方法
- 重载:发生在同一类中,方法名相同,参数列表不同
- 方法名相同的完全不同的方法
- 重写:发生在父子类中,方法名相同,参数列表相同
-
实例变量与静态变量的区别:
- 实例变量和静态变量都属于成员变量
- 实例变量:是属于对象的,在创建对象时存储在内存堆中,创建多少个对象,则实例变量就会在内存堆中存在多少份,需要通过引用变量来访问
- 静态变量:是属于类的,在类被加载时存储在内存方法区中,无论创建多少个对象,静态变量在内存中都只有一份,常常通过类名点来访问
- 实例变量和静态变量都属于成员变量
-
java是值传递还是引用传递?
- 在java中,无论是基本类型还是引用类型,都是值传递
- 对于基本类型而言,传递的是具体的值的副本-------身份证复印件
- 对于引用类型而言,传递的是具体的地址的副本-----房子+钥匙
- 在java中,无论是基本类型还是引用类型,都是值传递
-
抽象类与接口的区别:
- 抽象类:
- 由abstract修饰
- 可以包含变量、常量、构造方法、普通方法、静态方法、抽象方法
- 派生类通过extends来继承
- 只能继承一个(体现单一继承)
- 抽象类中的成员,任何访问权限都可以(默认为默认权限(同包中))
- 接口:
- 由interface定义
- 只能包含常量和抽象方法
- 实现类通过implements来实现
- 可以实现多个(体现多实现)
- 接口中的成员,访问权限只能是public(默认public权限)
- 抽象类:
-
String s = new String("hello"); 创建了几个对象?
- 答:两个,一个是hello字面量对象,另一个是new出来的对象
-
==和equals()的区别:
-
==可以作用于基本类型,也可以作用于引用类型:
- 若为基本类型,则是在比较值是否相等
- 若为引用类型,则是在比较地址值是否相等
-
equals()只能作用于引用类型:
-
Object类的equals()默认比较的还是==(即比较地址),但是没有参考意义,所以常常需要重写equals()来比较对象的属性值是否相同
注意:String类重写了equals()来比较字符串内容是否相同
包装类也重写了equals()来比较值是否相同
-
-
-
String常用的方法有哪些?
- length():获取字符串的长度(字符个数)
- trim():去掉两边的空白字符
- toUpperCase()/toLowerCase():将英文部分给转换为全大写/全小写字母
- startsWith()/endsWith():判断是否是以???开始/结束的
- charAt():根据下标找字符
- indexOf()/lastIndexOf():查找字符串第一次出现/最后一次出现的下标
- substring():截取字符串
- 静态方法valueOf():将其它类型的数据转换为字符串
- matches():验证匹配(正则表达式)
- replaceAll():替换(正则表达式)
- split():拆分(正则表达式)
-
String、StringBuilder、StringBuffer的区别:
- String:
- 由final修饰,所以不能被继承。底层封装的是final的字符数组,所以为不变对象。每次修改String引用变量的值,都是在创建新的对象。适合查看,但不适合频繁修改。在实际应用中对于字符串大部分情况下都是在查看,所以String的应用率最高。
- StringBuilder:
- 底层封装的是字符数组,所做操作就是在该数组之上的,修改效率高。
- 非线程安全的,并发处理的,性能稍快-------------一般都是用StringBuilder
- StringBuffer:
- 底层封装的是字符数组,所做操作就是在该数组之上的,修改效率高。
- 线程安全的,同步处理的,性能稍慢-----------------应用率不高
- String:
-