目录
4.Object的public String toString()
1.Scanner类:文本扫描器,java.util.Scanner;
二、StringBuffer和String类型的相互转换以及作为形式参数的区别
1. .构造方法:public Character(char value)
5.集合在使用迭代器时会经常出现的异常:ConcurrentModificationException:并发修改异常
7.26日
一.局部内部类,访问外部类或成员变量
1.局部内部类
书写位置在外部类的成员方法中,局部内部类可以访问外部类的成员变量包括其私有变量。
在外部类的局部位置,访问内部类的成员方法,创建当前局部内部类对象来访问。
2.面试题:
局部内部类访问局部变量时,应该注意什么?
如果此时Java环境是JDK7,那么局部内部类访问局部变量时,此时该变量必须显示关键字final修饰。
如果此时Java环境为JDK8及以上,则final关键字可以省略。
原因:局部变量的生命周期是随着方法调用而存在,随着方法调用的结束而消失,而当前外调用method 方法的时候,此时num进入栈内存,在局部位置创造了局部内部类对象,而局部内部类对象调用它的成员方法访问该变量,方法method结束后,内部类对象不会立刻消失,它里面的成员方法在访问局部变量,局部变量必须变成常量常驻内存,否则如果当前变量消失了,局部内部类的成员却依然在访问,就会出现冲突,所以JDK7必须加入final修饰,JDK8通过jvm已经进行了优化,所以无需写明final。
class Outer2{
public void method(){
int num = 20 ; //局部变量
class Inner2{
public void show(){
System.out.println(num);
}
}
//创建Inner2类对象
Inner2 inner2 = new Inner2() ;
inner2.show();
}
}
public class OuterDemo2 {
public static void main(String[] args) {
//创建Outer2对象
Outer2 outer2 = new Outer2() ;
outer2.method();
}
}
二、匿名内部类
1.匿名内部类:
没有名字的内部类,一般在局部位置使用。格式:
匿名内部类是内部类的一种简化格式
new 类名 (可抽象可具体)或接口名(){
重写功能};
匿名内部类的本质是:继承了该类或者实现了该接口的子类对象。
2.形参问题:
方法的形式参数如果是一个接口,实际需要传递的接口的子实现类对象。
方式1:将接口的子实现类定义出来
方式2:使用接口的匿名内部类
interface Mary{
void mary() ;
}
//定义一个LoveDemo类
class LoveDemo{
public void funciton(Mary mary){//形式参数是一个接口
mary.mary();
}
}
//定义一个子类实现类
class You implements Mary{
@Override
public void mary() {
System.out.println("要结婚了,很开心...");
}
}
//测试类
public class LoveTest {
public static void main(String[] args) {
//方式1:需要调用LoveDemo类中的function方法
LoveDemo loveDemo = new LoveDemo() ; //或者使用匿名对象
//接口多态
Mary mary = new You() ;
loveDemo.funciton(mary);
System.out.println("----------------------------------------");
//方式2:接口的匿名内部类
//创建LoveDemo类对象
LoveDemo ld = new LoveDemo() ;
ld.funciton(new Mary() {
@Override
public void mary() {
System.out.println("要结婚了,很开心...");
}
});
}
}
3.匿名内部类在开发中的使用:
方法的形式参数如果是一个抽象类,那么实际参数需要接口的子类对象。
方法1:将子类定义出来,继承自抽象类
方法2:直接使用抽象类的匿名内部类
class Student extends Person{
@Override
public void work() {
System.out.println("good good study ,day day up!!");
}
}
//测试类
public class PersonTest {
public static void main(String[] args) {
//调用PersonDemo类中的method方法?
//创建PersonDemo类对象 /或者匿名对象
PersonDemo pd = new PersonDemo() ;
//抽象类多态:创建子类对象
Person p = new Student() ; //定义一个子类Student
pd.method(p) ;
System.out.println("----------------------------------------");
//使用匿名内部类去完成:
/**
* new 类名(抽象类)/接口名(){
* 重写方法
* } ;
*/
//调用PersonDemo类中的method方法?
PersonDemo pd2 = new PersonDemo() ;
pd2.method(new Person(){ //实际参数也是传递抽象类的子类对象(抽象类的匿名内部类)
@Override
public void work() {
System.out.println("good good Study,day day Up!!");
}
});
}
}
三、方法返回值问题
1.返回值是一个抽象类
需要返回的是当前抽象类的子类对象。
2.返回值是接口类型
需要返回的是当前接口的子实现类对象。
四、常用类
1.Object
它是类结构层次的上帝,所有的类都默认继承自Object子类(派生类)
2.使用API学习常用类的常用功能。
Object功能类的getClass()方法
1) public final Class getClass();表示正在运行的类(Class文件对象)
2)public String getName(); 获取当前类的全限定名称(包名,类名)
Object类中的getClass()/finalize()/hashCode()以及以后常用类
功能中如果有native关键字,则表示是本地方法,非JAVA语言底层实现。
3)public int hashCode();获取对象的哈希码值
3.面试题:获取一个类的字节码文件对象有哪几种方式?三种
1)通过Object类的getClass()——>Class
2)任意JAVA类型的class属性
3)Class里面forName(“类的全限定名称(包名.类名)”)
4.Object的public String toString()
返回值对象的字符串表达形式,结果应该是一个简明的表达式,建议所有子类覆盖此方法(重写)。
5.Object的equals方法
public boolean equals(Object obj)判断当前对象是否和obj对象相等。
6.面试题:equals 和==的区别?
==:连接基本数据类型,比较的是数据值是否相同。
连接引用类型时,比较的是地址值是否相同。
equals:如果使用Object默认的方法:比较的还是两个对象的地址值是否相同,
如果重写Object的equals方法,比较的就是两个对象的内容是否相同。
7.27
一、Object的clone方法:
1.克隆方法:
此处为浅克隆,即将地址值赋值给对象。
2.异常:
proteceed Object clone()创建对象并返回该对象的副本,这个方法会抛出一个异常,throws 表示的是可能出现异常,针对调用者必须进行处理
要使用clone方法,就必须实现“标记接口”Cloneable,
实现了这个接口,就可以使用Object的clone()方法
public class ObjectDemo {
public static void main(String[] args) throws CloneNotSupportedException{
//创建学生对象
Student s1 = new Student("高圆圆",42) ;
System.out.println(s1);
System.out.println(s1.getName()+"---"+s1.getAge());
System.out.println("-----------------------------------");
//调用克隆方法clone()
Object obj = s1.clone(); //已经克隆了(浅克隆:将s1地址值赋值给Objet)
//向下转型
Student s2 = (Student) obj;
System.out.println(s2);
System.out.println(s2.getName()+"---"+s2.getAge());
System.out.println("-----------------------------------");
//传统方式
Student s3 = s1 ;
System.out.println(s3.getName()+"---"+s3.getAge());
}
}
二、Scanner类
1.Scanner类:文本扫描器,java.util.Scanner;
构造方法:
public Scanner (InputStream source):创建一个文本扫描器,形参为抽象类。
2.Scanner类判断功能:
目的是:为防止出现输入的类和结果类不匹配。
public boolean hasNextInt()
public class ScannerDemo {
public static void main(String[] args) {
//创建键盘录入对象
InputStream inputStream = System.in ; //标准输入流 IO(Input 读 ,Output 写) :Java高级特性:IO
Scanner sc = new Scanner(inputStream) ;// public Scanner(InputStream source) :创建一个文本扫描器
System.out.println("请您输入一个数据:");
if(sc.hasNextInt()){
int num = sc.nextInt() ;
System.out.println("您录入的数据是:"+num);
}else if(sc.hasNextLine()){
//录入的字符串
String line = sc.nextLine() ;
System.out.println("您录入的数据是:"+line);
}else{
System.out.println("您录入的数据和结果类型不匹配...");
}
//录入数据
// int num = sc.nextInt(); //java.util.InputMismatchException
// System.out.println("您要录入的数据是:"+num);
}
}
三、String类
1.String特点:
代表字符串,字符串是一个常量,一旦被赋值,其值(地址值)不能被改变。
2.String类的常用功能
1)获取功能
int length():获取字符串的长度
public char charAt(int index);获取指定索引处的字符
public String concat(String str):将指定的字符串和当前字符串进行拼接,获取一个新的字符串
public int indexOf(int ch):返回指定字符第一次出现的索引值
public int lastIndexOf(int ch):返回值指定字符最后一次出现的索引值
public String[] split(String regex): 拆分功能:通过指定的格式将字符串---拆分字符串数组
public String substring(int beginIndex) :从指定位置开始默认截取到末尾, 角标从0开始
public String substring(int beginIndex,int endIndex):从指定位置开始,截取到位置结束(包前不包右),只能取到endIndex-1处
public static String valueOf(boolean/int/long/float/double/char...Object b):万能方法,将任意类型转换String类型
2)转换功能(重点)
byte[ ] getBytes():将字符串转换成字节数组(编码)
byte[ ] getBytes(String charset):使用指定的字符集进行编码,将字符串转换成字节数组
String(byte[ ] bytes):使用默认的字符集进行解码
String ( byte[ ] byres,指定字符集):使用指定的字符集进行解码
编码解码必须保证字符集统一,否则乱码。
3)静态功能
public char[ ] toCharArry():将字符串转换成字符数组
public String toString(): 返回自己本身,即“当前字符串的内容”
public String toUpperCase(): 将字符串转换成大写
public String toLowerCase():将字符串转换成小写
4)判断功能
public boolean equals(Object anObject ):比较两个字符串的内容是否相同(区别大小写)
public boolean equalsIggnoreCase(String anotherString)比较两个字符串的内容是否相同(不区别大小写)
public boolean startsWith(String prefix): 判断字符串是否以指定的内容开头
public boolean endWith(String suffix): 判断字符串是否以指定的内容结尾
boolean isEmpty() 判断字符串是否为空:为空返回true,否则返回false
String s= "";//空字符串,存在String对象""
String s = null;//空值(空对象)null:引用类型的默认值
5)其他功能:
public String replace(char target, char replacement):替换功能,将指定的内容使用target进行替换
public String replaceAll(String regex, String replacement):将指定的和参数使用replacement进行替换
public String trim():去除字符串两端的空格
重点:public int compareTo(String anotherString):按照字典顺序比较,返回值是int
3.构造方法
public String() :空参构造
public String(byte[ ] bytes):将一个字节数组构造成一个字符串,使用平台默认的字符集解码。
public String (byte [ ] bytes,字符集):使用平台指定的字符集,将字节数组构造成一个字符串。
public String( char[ ] value):将字符数组构造成 一个字符串
public String(char[ ] value,int offset, int count):将部分字符数组转换成字符串
public String(String original):构造一个字符串,参数是字符串常量
4.面试题
1)在数组中有没有length方法,在String类中有没有length方法,在集合中有没有length方法?
数组中没有length方法,但是又length属性
String类中有length方法
集合中没有length(),但是有size()来获取元素数
2)String S1= "hello";String S2= new String("hello");在内存中分别创建了几个对象?
第一个创建了一个对象,直接在常量池中创建,开辟常量池空间。(直接在常量池中找,如果存在就返回地址,如果不存在,就在常量池开辟空间。)
第二个创建了两个对象,一个在堆内存中开辟空间,一个指向常量池。(创建了俩个对象,堆内存中创建对象,而且常量标记还需要再常量池中找是否存在“hello”这个常量)
public class StringTest {
public static void main(String[] args) {
String s1 = "hello" ;
String s2 = "world" ;
String s3 = "helloworld" ;
System.out.println(s3 == (s1+s2)); //s1+s2:先开空间,在拼接 false
System.out.println(s3.equals(s1+s2)); //true
System.out.println("----------------------");
System.out.println(s3 == "hello"+"world"); //先拼接,然后再常量池中找,存在,直接返回地址
System.out.println(s3 .equals("hello"+"world"));
}
}
3) String s1 = "hello" ;String s2 = "hel" ; 使用s1调用compareTo(s2):按照字典顺序比较:结果是多少?是怎么运行的? 长度相减
String s1 = "hello" ; "abc"
String s2 = "hel" ; "hello"
s1.compareTo(s2) ;
class String{
private final char value[];//value属性
//按照字典顺序比较
public int compareTo(String anotherString) { //s2
int len1 = value.length; //计算第一个字符数组的长度 s1.value.length = 5 3
int len2 = anotherString.value.length;//s2.value.length---->3 5
int lim = Math.min(len1, len2); //Math.min(5,3) ---->lim = 3 3
char v1[] = value; //char v1[] = s1.value= {'h','e','l','l','o'} {'a','b','c'}
char v2[] = anotherString.value;//char v2[] = s2.value = {'h','e','l'} {'h','e','l','l','o'}
int k = 0; //统计变量k = 0
while (k < lim) { 0 < 3 1< 3 2< 3 3< 3 (不成立)
char c1 = v1[k]; //char c1 = v1[0] ='h' //char c1 = v1[1] = 'e' // char c1 = v1[2] = 'l' char c1 = v1[0] ='a'
char c2 = v2[k]; //cahr c2 = v2[0] = 'h' //char c2 = v2[1] = 'e' // char c2 = v2[2] = 'l' char c2 = v2[1] ='h'
if (c1 != c2) {
return c1 - c2; //c1- c2 = 'a' - 'h' = 97 - 104 = -7
}
k++; //k=1 2 3
}
return len1 - len2; //len1 - len2 = 5 -3 = 2
}
四、StringBuffer类
1.特点
StringBuffer:字符串缓冲区,类似于String,但是不同。
2.构造方法:
public StringBuffer();空参构造,创建一个空字符序列的字符串缓冲区
public StringBuffer(int Caoacity):构造一个字符出啊缓冲区对象,指定容量大小
public StringBuffer(String str):指定字符序列,长度加上初始容量16
获取功能:
public int length(): 获取字符串长度
public int capacity():获取字符串缓冲区容量
7.28
一、StringBuffer功能:
1)添加功能:
StringBuffer append(任何类型):将内容追缴到字符串缓冲区中,返回值是字符串缓冲区本身。
public StringBuffer insert(int offset,String str):插入,再指定位置处插入指定内容。
2)删除功能:
public StringBuffer delectChart(int index):删除指定索引处的缓冲区子房湖序列,返回字符串缓冲区本身
public StringBuffer delete(int start,int end ):删除从指定位置到指定位置结束的字符序列(end-1处)
3)特有功能:
public StringBuffer reverse():反转功能,将目标字符串进行反转
4)截取功能:
public String substring(int start):从指定位置开始,默认截取到末尾,返回值是新的字符串
public String substring(int start,int end):从指定位置开始到指定end-1结束进行截取,返回的新的字符串
5)替换功能:
public StringBuffer replace(int start,int end ,String str) :(起始索引值,终止索引值,替换内容)
二、StringBuffer和String类型的相互转换以及作为形式参数的区别
1.StringBuffer和String类型的相互转换
开发中:数据 本身为A类型,由于需要使用B类型的功能,所以需要将A类型转换为B类型。B类型使用完毕后,可能结果又需要A类型,所以又将B类型转化为A类型。
public class StringBufferDemo3 {
public static void main(String[] args) {
//String---->StringBuffer
String s = "hello" ;
//错误的写法
// StringBuffer sb = s ;//两个类型不一致
//方式1:StringBuffer有参构造方法
StringBuffer sb = new StringBuffer(s) ;
System.out.println(sb);
System.out.println("---------------------------");
//方式2:StringBuffer的无参构造方法 结合append(String str)
StringBuffer sb2 = new StringBuffer() ;
sb2.append(s) ;//追加功能
System.out.println(sb2);
System.out.println("-------------------------------------------");
//StringBuffer---->String
//创建字符串缓冲区对象
StringBuffer buffer = new StringBuffer("helloJavaee") ;
//方式1:String类型的构造方法
//public String(StringBuffer buffer)
String str = new String(buffer) ;
System.out.println(str);
System.out.println("-------------------------------------------");
//方式2:StringBuffer的public String toString()方法
String str2 = buffer.toString();
System.out.println(str2);
}
}
2.面试题:
1)StringBuffer和数组的区别?
数组:只能存储同一种数据类型的容器,数组可以存储基本类型,也可以存储引用类型,数组的长度是固定的。
StringBuffer:支持可变的字符序列,;i面可以存储任意类型的元素。
2)String,StringBuffer,StringBuilder的区别是什么?
String:字符串是一个常量,一但被赋值,其值不能被更改,作为形式参数属于特殊的引用类型形式参数的改变不会影响实际参数。
StringBuffer:可变的字符序列,线程安全的类,是同步的,但是执行效率低。
StringBulider:可变的字符序列,和StringBuffer具有相互兼容的API,单线程程序(只考虑速率,不考虑安全)中会使用它来代替StringBuffer。
三、Integer类
1.概念:
Integer:int 类型的包装类型(引用类型),包含了int类型的原始数据。
为什么需要包装类型?
因为需要将基本类型和String类型之间相互转换时,需要中间桥梁。
2.方法:
public static String toBinaryString(int i):将整数---->二进制 的字符串
public static String toOctalString(int i):将整数---->八进制的字符串
public static String toHexString(int i):将整数---->十六进制数据
public static final int MAX_VALUE:int的最大值
public static final int MIN_VALUE:int的最小值
3.构造方法:
Integer(int value):可以将int类转变为Interger类型
Integer(String s) throws NumberForamtException:抛出一个数字格式化异常,原因时当前字符串不是能够解析的整数。
4.JDK5以后的新特性:
自动拆装箱:是将基本类型转化为对应的包装类型(装箱)
将对应的包装类型转换为基本类型(拆箱)
自动拆装箱,可变参数,静态导入,增强for循环,<泛型>,枚举类
5.面试题:看程序写结果
public class IntegerTest {
public static void main(String[] args) {
Integer i1 = new Integer(127) ;
Integer i2 = new Integer(127) ;
System.out.println(i1==i2);//false
System.out.println(i1.equals(i2));//true
System.out.println("----------------------------");
Integer i3 = 127 ;//valueOf(127) 127 (-128~127) //直接从内部缓存区中取出数据并么有重新创建对象
Integer i4 = new Integer(127) ;
System.out.println(i3== i4);//false
System.out.println(i3.equals(i4));//true
System.out.println("-----------------------------");
Integer i5 = 128 ; //128已经超出了范围 :new Integer(128)
Integer i6 = new Integer(128) ;
System.out.println(i5==i6);
System.out.println(i5.equals(i6));
System.out.println("-------------------------------");
Integer i7 = 127 ;
Integer i8 = 127 ;
System.out.println(i7==i8);//true IntegerCache:缓存区取出数据
System.out.println(i7.equals(i8));//true
System.out.println("-------------------------------");
Integer i9 = 128 ;// 缓存区中范围:-128~127 return new Integer(128)
Integer i10 = 128 ;
System.out.println(i9==i10);//false
System.out.println(i9.equals(i10));//true
/* Integer i = 127 ;
System.out.println(i);*/
/**
* 翻译工具查看:执行底层的valuOf()
* Integer i = Integer.valueOf(127);
* System.out.println(i);
*/
}
}
数值在(-128~127之间时):直接从内部缓存区中取出数据并么有重新创建对象
数值超出范围时,会重新创建对象(new Integer(128))
四、Charcater类(char的包装类类型)
1. .构造方法:public Character(char value)
主要功能:
public static boolean isUpperCase(char ch):判断当前字符是否大写字母字符
public static boolean isLowerCAse(char ch):是否为小写字母字符
public static boolean isDigit(char ch):是否为数字字符
转换:
public static char toLowerCase(char ch):将字符转换成小写
public static char toUpperCase(char ch):将字符转换成大写
五、Calendar:类
提供一些诸如获取年月月中日期等等字段值的方法。抽象类,不能能实例化
方法:
public static Calendar getInstance()
成员方法:
public int get(int field):根据给定日历字段,获取日历字段的值(系统的日历)。
public abstract void add(int field,int amount):给指定的日历字段增加或者减去时间偏移量。
public class CalendarDemo {
public static void main(String[] args) {
//创建日历类对象
//获取系统的年月日
// Calendar c = new Calendar() ;
//public static Calendar getInstance()
Calendar calendar = Calendar.getInstance();
// System.out.println(calendar);
//获取年
//public static final int YEAR
int year = calendar.get(Calendar.YEAR) ;
//获取月:
//public static final int MONTH:0-11之间
int month = calendar.get(Calendar.MONTH) ;
//获取月中的日期
//public static final int DATE
//public static final int DAY OF MONTH : 每个月的第一天1
int date = calendar.get(Calendar.DATE) ;
System.out.println("当前日历为:"+year+"年"+(month+1)+"月"+date+"日");
System.out.println("------------------------------------------------");
//获取3年前的今天
//给year设置偏移量
// public abstract void add(int field,int amount)
// calendar.add(Calendar.YEAR,-3);
//获取
// year = calendar.get(Calendar.YEAR) ;
// System.out.println("当前日历为:"+year+"年"+(month+1)+"月"+date+"日");
//5年后的十天前
//需求:键盘录入一个年份,算出任意年份的2月份有多少天 (不考虑润月)
}
}
六、Date
1.Date概念
表示特定瞬间,精确到毫秒;它还允许格式化和解析日期字符串。
构造方法:
public Date():当前系统时间格式
public Date(long date):参数为时间毫秒值
2.Date与String类型之家的转换
DateFormat:抽象类,用来提供具体的日期/格式化的子类:SimpleDateFormat
format(Date对象)--->String
SimpleDateFormat:构造函数
public SimpleDateFormat():使用默认模式
public SimpleDateFormat(String pattern):使用指定的模式进行解析或者格式 (推荐)
参数:
一种模式
表示年 "yyyy"
表示月 "MM"
表示月中的日期 "dd"
一天中小时数 "HH"
分钟数 "mm"
秒数 "ss"
String:日期文本----->Date
解析过程
public Date parse(String source)throws ParseException
如果解析的字符串的格式和 public SimpleDateFormat(String pattern)的参数模式不匹配的话,就会出现解析异常!
public class DateUtils {
//构造方法私有化
private DateUtils(){}
//提供两个静态功能
//Date---->String
/**
* 这个方法是针对将日期对象转换成日期文本字符串
* @param date 需要被格式化的日期对象
* @param pattern 需要指定的模式
* @return 返回的日期文本字符串 结果 yyyy-MM-dd
*/
public static String date2String(Date date,String pattern){
//分步走
//创建SimpleDateFormat对象
/* SimpleDateFormat sdf = new SimpleDateFormat(pattern) ;
String result = sdf.format(date);
return result ;*/
//一步走
return new SimpleDateFormat(pattern).format(date) ;
}
//String--->Date: 解析过程: parse(String source) throws ParseException
/**
* 这个方法针对String日期文本字符串转换成日期对象
* @param source 需要被解析的日期文本字符串
* @param pattern 需要解析中使用的一种模式
* @return 返回的就是日期对象Date
*/
public static Date string2Date(String source,String pattern) throws ParseException {
return new SimpleDateFormat(pattern).parse(source) ;
}
}
7.29
一、Math类
针对数学运算的工具类,提供了很多方法
public static int abs(int a):绝对值方法
public static double ceil(double a):向上取整
public static double floor(double a):向下取整
public static int max(int a,int b):获取最大值
public static int min(int a,int b):获取最小值
public static double pow(double a,double b):a的b次幂
public static double random():[0.0,1.0):随机数
public static long round(double a):四舍五入
public static double sqrt(double a):开平方根
Math类中的功能都是静态的,里面构造方法私有了!
一般情况:工具类中构造方法都是会私有化(自定义的工具类),提供对外静态的公共访问方法
Math类的功能都是静态的,支持静态导入:import static 包名.类名.方法名;
二、Random类
构造方法
public Random(): 产生一个随机生成器对象,通过成员方法随机数每次没不一样的(推荐)
public Random(long seed) :参数为long类型的值(随机数流:种子),每次通过成员方法获取随机数产生的随机数相同的
获取随机数的成员方法
public int nextInt():获取的值的范围是int类型的取值范围(-2的31次方到2的31次方-1)
public int nextInt(int n):获取的0-n之间的数据 (不包含n)
三、BigDecimal
用于小数要进行精确计算时,可以计算的同时保留小数点后的有效位数
构造方法
public BigDecimal(String value):数字字符串
成员方法:
public BigDecimal add(BigDecimal augend)加
public BigDecimal subtract(BigDecimal subtrahend)减
public BigDecimal multiply(BigDecimal multiplicand)乘
public BigDecimal divide(BigDecimal divisor):除
public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode)
参数1:商,参数2:小数点后保留的有效位数,参数3:舍入模式 :四舍五入
四、Collection集合
1.概念
Collection:集合层次的根接口,一些集合允许元素重复(List),一些集合不允许元素重复(Set)
一些集合有序(存储和取出一致)(List),一些集合无序(存储和取出不一致)(Set),
JDK不提供此接口的任何直接实现:它提供了更具体的子接口的实现,如Set和List
Collection:
List:最具体的子实现类ArrayList,LinkedList,Vector
2.基本功能:
添加:boolean add(Object e):添加元素
删除:void clear():暴力删除集合中的所有元素
boolean remove(Object o):从集合中删除指定的元素
获取元素数:int size();
判断: boolean isEmpty();判断是否为空,空则返回true
boolean contains(Object o):判断集合中是否包含指定元素,包含则返回true
3.高级功能
boolean addAll(Collection c):添加一个集合中的所有元素
boolean containsAll(Collection c):包含一个集合中的所有元素
boolean removeAll(Collection c):删除集合中的所有元素
boolean retainAll(Collection c):A集合对B集合求交集
Object[] toArray():将集合转换成了对象数组
4. Collection的迭代器
集合的专用遍历方式,Iterator iterator():返回值类型接口类型,需要返回的子实现类对象
Iterator接口: boolean hasNext():判断迭代器中是否存在下一个元素,Object next(): 获取下一个可以遍历的元素
public class CollectionTest2 {
public static void main(String[] args) {
//创建集合对象
Collection c = new ArrayList();
//创建4个学生
Student s1 = new Student("诸葛亮",45) ;
Student s2 = new Student("庞统",30) ;
Student s3 = new Student("周瑜",35) ;
Student s4 = new Student("吕布",25) ;
c.add(s1) ;
c.add(s2) ;
c.add(s3) ;
c.add(s4) ;
// c.add("hello") ;
//获取迭代器
Iterator iterator = c.iterator();
while(iterator.hasNext()){
// Object obj = iterator.next();
Object obj = iterator.next();
// System.out.println(obj);
// String s = (String)obj ;
// System.out.println(s);
Student s = (Student)obj ;
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
5.JDK5以后的新特性:
泛型<E/T>格式:<引用数据类型> 模拟数组创建的时候,就已经明确了数据类型
集合类型<引用数据类型> 集合对象名 = new 子实现类<引用数据类型>() ;
泛型的好处:
1)将运行时期的异常提前了编译时期
2)避免了强制类型转换
3)提高了程序的安全性
7.30
一、List集合
1.List集合特点:
有序(存储元素和去除元素一直)
允许元素重复
2.具备Collection相关功能
Object [ ] toArray()
Iterator iterator()
3.特有功能
void add(int index,Object element):在指定的索引处插入元素
Object get(int index):获取指定位置处的元素 +int size():一种新的集合遍历方式
Object remove(int index):删除指定位置处的元素
Object set(int index,E element):修改指定位置处的元素(替换)
ListIterator<E> listIterator():列表迭代器
void add(E e):添加
remove():删除
4.List集合的遍历方式:
1. Object[] toArray()
2. Iterator iterator()
3. Object get(int index):获取指定位置处的元素 + int size():一种新的集合遍历方式
4. ListIterator<E> listIterator():列表迭代器 :List集合专有遍历方式
5.增强for
public class ListTest {
public static void main(String[] args) {
//创建List集合对象
List<String> list = new ArrayList<>() ;
//添加元素
list.add("hello");
list.add("world");
list.add("java");
list.add("android");
//size()+get(int index)集合
for(int x = 0 ; x < list.size() ; x ++){
String s = list.get(x);
System.out.println(s+"---"+s.length());
}
System.out.println("-----------------------------------------------");
//List集合存储Student对象并进行遍历(学生:姓名,年龄)
List<Student> stuList = new ArrayList<>() ;//JDK7以后 泛型推断:自动的和前面的泛型类型一致!
//创建3个学生
Student s1 = new Student("张佳宁",31) ;
Student s2 = new Student("迪丽热巴",29) ;
Student s3 = new Student("张俊杰",20) ;
//添加到列表中
stuList.add(s1) ;
stuList.add(s2) ;
stuList.add(s3) ;
//遍历
//方式1:Object[] toArray()
Object[] objs = stuList.toArray();
for(int x = 0 ; x < objs.length ; x ++){
Student s = (Student) objs[x];
System.out.println(s.getName()+"----"+s.getAge());
}
System.out.println("--------------------------------------");
//Collection的迭代器
Iterator<Student> it = stuList.iterator();
while(it.hasNext()){
Student s = it.next() ;
System.out.println(s.getName()+"---"+s.getAge());
// System.out.println((it.next().getName()+"---"+(it.next().getAge())));
// next()只能使用一次,不能多次使用 //错误的用法
}
System.out.println("-------------------------------------");
//方式3:size()+get(int index)
for(int x = 0 ; x < stuList.size() ; x ++){
Student s = stuList.get(x);
System.out.println(s.getName()+"----"+s.getAge());
}
System.out.println("-----------------------------------------");
//正向遍历:ListIterator<E> listIterator():列表迭代器 :List集合专有遍历方式
ListIterator<Student> lit = stuList.listIterator();
while(lit.hasNext()){
Student student = lit.next();
System.out.println(student.getName()+"---"+student.getAge());
}
System.out.println("-----------------------------------------");
//逆向遍历:前提:必须有正向遍历
//ListIterator<E> listIterator()
//ListIterator:特有功能:
//boolean hasPrevious():是否有上一个元素可以迭代
//Object previous():获取上一个元素
while(lit.hasPrevious()){
Student student = lit.previous();
System.out.println(student.getName()+"---"+student.getAge());
}
}
}
5.集合在使用迭代器时会经常出现的异常:ConcurrentModificationException:并发修改异常
当集合的元素正在被迭代器进行遍历,那么集合对象是不能够对元素进行增加或者删除 (一个线程正在遍历,一个线程在修改元素)。
解决方法:
1:单独使用迭代器遍历集合元素,然后迭代器区添加元素。(列表迭代器才具备添加功能)
2:要么集合遍历,集合添加
public class ListTest2 {
public static void main(String[] args) {
//创建List集合对象
List<String> list = new ArrayList<>() ;
//给添加元素
list.add("hello") ;
list.add("world") ;
list.add("javaee") ;
//解决方案1: 1)要么就是迭代器去遍历集合的元素,迭代器去添加元素 :列表迭代器才具备添加的动作
//ListIterator
//void add(E e)
ListIterator<String> lit = list.listIterator();
while(lit.hasNext()){
//获取
String s = lit.next();
//判断是否存在"world"元素
if("world".equals(s)){
//列表迭代器添加
lit.add("javaEE");
}
}
//方案2:要么集合遍历,集合添加
//size()+get(int index)
for(int x = 0 ; x < list.size(); x ++){
String s = list.get(x);
if("world".equals(s)){//将常量放前面,防止出现NullPointerException
list.add("javaEE");
}
}
System.out.println(list);
}
}
二、增强for循环
JDK5以后 提供了增强for循环,替代集合中迭代器去遍历集合使用的(优先在集合中使用)
格式:
/*for(存储的引用数据类型 变量名: 集合/数组对象){ //集合使用居多,数组一般都是使用普通for
使用变量名即可
}
*/
for(String s:list){//获取迭代器
System.out.println(s+"---"+s.length());
}
注意事项:当前集合对象不能为空null:增强for它本身就是获取迭代器了,如果集合对象为空,就会出现空指针异常。
6.List集合去重:
方案1:新建空集合思想:集合中Collection/List--->contains(Object o)底层依赖于Object的equals方法,而List现在存储的是String类型,本身重写Object的equals,所以比较的是内容是否相同
方案2:利用选择排序的思想去完成:List集合---集合列表角标从0开始遍历当前集合,然后使用0角标对应的元素依次和后面对应的元素进行比较,如果后面的元素和前面的相同了,那么将后面的元素删除掉,角标自减一。
public class ListTest4 {
public static void main(String[] args) {
//创建一个List集合
List<Student> list = new ArrayList<>() ;
//创建一些学生对象:有重复的成员信息
Student s1 = new Student("高圆圆",42) ;
Student s2 = new Student("高圆圆",42) ;
Student s3 = new Student("刘诗诗",39) ;
Student s4 = new Student("刘诗诗",39) ;
Student s5 = new Student("张佳宁",30) ;
Student s6 = new Student("文章",36) ;
Student s7 = new Student("文章",36) ;
Student s8 = new Student("姚笛",32) ;
//添加到集合中
list.add(s1) ;
list.add(s2) ;
list.add(s3) ;
list.add(s4) ;
list.add(s5) ;
list.add(s6) ;
list.add(s7) ;
list.add(s8) ;
//方式1:创建新的一个新集合
List<Student> newList = new ArrayList<>() ;
//遍历以前的集合获取每一个学生对象
for(Student s:list){
//如果当前newList不包含这个学生添加到新集合中
if(!newList.contains(s)){
newList.add(s) ;
}
}
方案2:
//遍历新集合
for(Student student:newList){
System.out.println(student.getName()+"----"+student.getAge());
}
for (int i=0;i<list.size ()-1;i++){
for (int y=i+1;y<list.size ();y++){
if(list.get (y).equals (list.get (i))){
list.remove (y);
y--;
}
}
}
for(Sudent sudent:list){
System.out.println (sudent );
}
}
}
三、Vector集合
Vector集合特有的功能:
添加:public void addElement(Object obj):在vector对象的末尾添加元素
删除:public boolean removeElement(Object obj):删除元素
获取功能
public Object elementAt(int index):获取指定位置的元素
public Enumeration<E> elements() :Vector集合的专有遍历方式
类似于 Iterator literator()
接口:
boolean hasMoreElements():判断是否有更多的元素可以迭代
Object nextElement() 获取元素
四、插入排序:
核心思想: 核心思想:使用1角标对应的元素进行和0角标比较,如果前面元素大,向右移动,确定角标1对应的元素的位置,再次使用2角标对应的元素依次和1和0都元素比较,依此类推。
public class InsertSortTest {
public static void main(String[] args) {
//定义一个Integer数组: Integer实现的自然排序:元素能够按照升序默认排序
Integer[] arr = {34,8,64,51,32,21} ;
System.out.println("排序前:");
printArr(arr);
//定义一个功能
insertSort(arr) ;
System.out.println("排序后:");
printArr(arr);
}
//插入排序
private static void insertSort(Integer[] arr) {
//定义一个变量j
int j ; //j记录当前角标的变化
//定义变量 : p:表示一个比较次数 p=1,2,3,4,5 (每一移动的元素的位置)
for(int p = 1 ; p < arr.length ; p ++ ){ //比较次数 p=2
//定义临时变量temp
Integer temp = arr[p] ; //temp = 8; temp = 64
//开始比较
for(j = p ; j>0 && temp.compareTo(arr[j-1])<0; j-- ){ // j= 1 ; 1>0&& 8 < 34 j-- : j= 0
//j=2 ; 2>0 && 64 < 32
//数据移动
arr[j] = arr[j-1] ;
}
//确定temp的位置:8的位置 64的位置:p=2
arr[j] = temp ; // 没有移动
}
}
public static void printArr(Integer[] arr){
System.out.print("[");
for(int x = 0 ; x < arr.length ; x ++){
if(x == arr.length -1){
System.out.println(arr[x] +"]");
}else{
System.out.print(arr[x]+", ");
}
}
}
}