**千峰2021-2-1~5总结**
第一天
-
String和Stringbuffer作为形式参数的区别(重点)
String作为形式参数(是一种特殊引用类型)的特点:
形式参数的改变不会直接影响实际参数,它和基本数据类型作为参数是一样的
StringBuffer作为形式的特点:
形式参数改变会直接影响实际参数,和引用类型作为形式参数一样的
-
Integer:是int类型的包装类类型
Integer 类在对象中包装了一个基本类型 int 的值
Integer 类型的对象包含一个 int 类型的字段
-
为什么要学习这些基本类型的包装类类型呢?
举例:
int---->String,提供这些包装类型,就是为了让我们在基本类型和引用类型之间相互转换!(String)
基本类型 包装类类型(引用类型:默认值都是null)
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
-
Integer类的构造方法
public Integer(int value):将int类型数据构造成一个Integer对象
public Integer(String s):将String类型数据构造成一个Integer对象
throws NumberFormatException
注意:第二个构造方法传入的字符串必须是数字字符串
-
自动拆装箱:jdk5以后提供的新特性
自动装箱:举例:int类型会自动转换为Integer类型
自动装箱:举例:Integer会自动转成int类型
-
Integer i = 值; 执行 的valueIf(i) ;
Integer类的内部缓存区:-128~127之间:如果在范围内,直接从缓存区中取数据;如果不在范围内,new Integer(i) ;
-
关于int和String之间的类型转换
中间的桥梁:Integer的功能间接完成转换
int------>String 方式一:字符串的拼接,空串拼接任何数据都是字符串 int i=100; String s=" "+i; System.out.println(); 方式二:Integer---->String 利用Integer中方法:public static String toString(int i) int i=100; String s = Integer.toString(i); System.out.println(s); String---->int(重点) 方式一:Integer的静态功能:parseInt(String i)--->int(重点) //public static int parseInt(String s):s必须为数字字符串 //万能方法: String--->long: Long.paresLong(String s) String s="20"; int result3 = Integer.parseInt(s); System.out.println(result3); 方式二:利用 public int intValue()方法 String s="20"; Integer integer = new Integer(s) ; int result4 = integer.intValue(); System.out.println(result4)
-
Character:
Character 类在对象中包装一个基本类型 char 的值。
Character 类型的对象包含类型为 char 的单个字段。
构造方法: public Character(char value)
-
Character类中的常用功能
判断功能:
public static boolean isDigit(char ch)确定指定字符是否为数字。
public static boolean isLowerCase(char ch)确定指定字符是否为小写字母。
public static boolean isUpperCase(char ch)确定指定字符是否为大写字母。
键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符的个数?(不考虑其他字符) public class CharacterTest { public static void main(String[] args) { //定义三个统计遍历 int bigCount = 0 ; int smallCount = 0 ; int numberCount = 0 ; //创建键盘录入对象 Scanner sc = new Scanner(System.in) ; //提示并接收数据 System.out.println("请您输入一个字符串数据:") ; String line = sc.nextLine() ; //将字符串转换成字符数组 char[] chs = line.toCharArray(); //遍历字符数组 for(int x = 0 ; x < chs.length ; x ++){ char ch = chs[x] ; //直接判断 if(Character.isUpperCase(ch)){ bigCount ++ ; }else if(Character.isLowerCase(ch)){ smallCount ++ ; }else if(Character.isDigit(ch)){ numberCount ++ ; } } System.out.println("大写字母字符共有:"+bigCount+"个"); System.out.println("小写字母字符共有:"+smallCount+"个"); System.out.println("数字字符共有:"+numberCount+"个"); } }
-
System类:主要用来提供一字段以及一些实用的方法,它不能实例化
字段:
public static final InputStream in: “标准输入流”
System.in—>InputStream inputStream:录入数据/读取数据----后期IO流中讲: 字节输入 流:可以读取字节
public static final PrintStream out “标准输出流”
System.out.println(“hello”) ;
原理:
System.out----->PrintStream字节打印流 ---->后期IO流中讲
println():是字节打印流中的成员
成员方法
public static void gc():运行垃圾回收器。
调用gc 方法暗示着 Java 虚拟机做了一些努力来回收未用对象,以便能够快速地清除这些对象当前占用的内存。
等价于:Runtime.getRuntime().gc();
-
final,finally,finalize()的区别?
final:可以修饰类,类不能被继承
可以修饰成员方法,此时这个方法不能被重写
可以修饰成员拜年了,此时变量是一个常量
finalize():当前垃圾回收器开启的时候,会调用finalize()回收没有更多引用的对象
(底层会有一种标记清除的算法(系统资源将其删除))
-
复制数组的操作:(System)
public static void arraycopy(Object src,int srcPos, Object dest,int destPos,int length)
从源数组中的某个位置开始复制length长度到指定的目标数组中的某个位置结束
参数1:源数组
参数2:从源数组指定的位置开始
参数3:目标数组
参数4:目标数组中的某个位置开始
参数5:复制的长度
-
public static void exit(int status):终止当前正在运行 Java虚拟机
System.exit(0); ------>0表示正常终止jvm
public static long currentTimeMillis():返回以毫秒为单位的当前时间
long start = System.currentTimeMillis() ; for(int x = 0 ; x < 100000; x ++){ System.out.println("hello:"+x); } long end = System.currentTimeMillis() ; System.out.println("共耗时"+(end-start)+"毫秒");//耗时1969
-
Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,
并为操作日历字段(例如获得下星期的日期)提供了一些方法
实例化:
public static Calendar getInstance():用默认时区和语言环境获得一个日历
成员变量:
public static final int YEAR;获取年份
public static final int MONTH;获取月份 :从角标0开始计算
public static final int DATE:月中的日期
成员方法:
public int get(int field)返回给定日历字段的值
public class CalendarDemo { public static void main(String[] args) { //创建日历类对象 //Calendar c = new Calendar() ;//抽象类的不能实例化 //如果一个类没有抽象方法,能不能定义为抽象类呢? 可以,目的就是为了不能让当前这个类能够直接创建对象, //要么它子类对象,要么就是当前类里面有一个静态功能返回值是它本身,(有具体的子类) Calendar c = Calendar.getInstance();//此处就是一种多态:层层继承获取到的日历实例 //获取年 int year = c.get(Calendar.YEAR); //获取月份: int month = c.get(Calendar.MONTH) ; //获取月中的日期 int date = c.get(Calendar.DATE) ; System.out.println(year+"年"+(month+1)+"月"+date+"日"); } }
-
(Calendar)成员方法:
public abstract void add(int field,int amount):为日历中指定的字段添加或者减去时间偏移量
public final void set(int year,int month,int date):自己设置年月日(日历对象.set(2018,5,12) )
Calendar c2 = Calendar.getInstance() ; //需求:5年后的10天前 ----- c2.add(Calendar.YEAR,+5); int year2 = c2.get(Calendar.YEAR) ; int month2 = c2.get(Calendar.MONTH) ; c2.add(Calendar.DATE,-10);
-
日期类:
Date表示特定的瞬间,精确到毫秒。 (开发中经常用:举例: 数据库中的出生日期/日期格式
构造方法:
public Date():创建日期对象
public Date(long date):
分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。
第二天
-
Date—>java.util.Date:日期类:精确到毫秒
成员方法:
public long getTime() : 将date—long
返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
public void setTime(long time):设置一个时间毫秒值
以表示 1970 年 1 月 1 日 00:00:00 GMT 以后 time 毫秒的时间点。
-
Date和String之间的相互转换
java.text.DateFormat 是日期/时间格式化子类的抽象类
当前DateFormat是一个抽象类,抽象类不能直接实例化,提供具体的已知的子
类:SimpleDateFormat
(1)Date----->String --> 日期---->文本 格式化
public final String format(Date date)
步骤:
1)需要存在Date对象
2)public SimpleDateFormat(String pattern):参数为一个模式
模式要符合格式:
y—年 yyyy:表示具体的年份
M 年中的月份 MM:表示月份
d 月份中的天数 dd:表示月中天
H:一天中的小时
m:小时中的分钟数
s:秒
HH:mm:ss:时分秒
3)调用format(Date date)—>String
//Date--->String 格式化的过程 //创建Date对象 Date date = new Date() ; System.out.println(date);;//Tue Feb 02 10:38:47 CST 2021 //中间桥梁:创建SimpleDataFormat 对象 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss") ; String dateStr = sdf.format(date); System.out.println(dateStr);
(2)String---->Date---->文本---->日期 解析
public Date parse(String source)
throws ParseException :此方法在调用的时候会抛出一个异常:解析异常!
步骤
1)需要存在Date对象
2)public SimpleDateFormat(String pattern):参数为一个模式
模式要符合格式:
y—年 yyyy:表示具体的年份
M 年中的月份 MM:表示月份
d 月份中的天数 dd:表示月中天
H:一天中的小时
m:小时中的分钟数
s:秒
HH:mm:ss:时分秒
3)调用parse方法:解析—抛出异常
//String--->Date :解析 //存在字符串文本 String str = "2008-5-12" ; //创建SimpleDataFormat对象 SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd") ; //解析 Date date2 = sdf2.parse(str); System.out.println(date2);//Date日期格式 注意: 将String---Date: 解析中必须保证SimpleDateFormat中的模式和日期文本格式的一致,否则解析异常!
-
BigDecimal构造方法
public BigDecimal(String val):里面做小数精确计算,里面的内容应该是数字字符串
成员方法
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, 保留几位小数
RoundingMode roundingMode) 指定模式:四舍五入(常量)
RoundingMode:枚举类 :都定义的常量
可以使用BidDecimal里面的字段
public static final int ROUND_HALF_UPpublic class BigDecimalDemo { public static void main(String[] args) { //创建BigDicmal对象 BigDecimal bg1 = new BigDecimal("1.00"); BigDecimal bg2 = new BigDecimal("0.01"); System.out.println(bg1.add(bg2)); System.out.println("---------------------------------"); BigDecimal bg3 = new BigDecimal("1.01") ; BigDecimal bg4 = new BigDecimal("0.06") ; System.out.println(bg3.subtract(bg4)); System.out.println("---------------------------------"); //3.05*1.2 BigDecimal bg5 = new BigDecimal("3.05") ; BigDecimal bg6 = new BigDecimal("1.2") ; System.out.println(bg5.multiply(bg6)); System.out.println("---------------------------------"); //1.501/0.1 BigDecimal bg7 = new BigDecimal("1.501") ; BigDecimal bg8 = new BigDecimal("0.1") ; System.out.println(bg7.divide(bg8)); System.out.println("--------------------------------"); System.out.println(bg7.divide(bg8,3,BigDecimal.ROUND_HALF_UP)); } }
-
Random:类:随机数生成器 此类的实例用于生成伪随机数流
构造方法
空参构造:Random() :
通过nextInt():产生的随机数是不同的
有参构造
Random(long seed):
通过nextInt():产生的随机数是相同的(不推荐)
成员方法:
public int nextInt(int n):获取的是[0,n):之间的数据
public int nextInt() :获取的是int类型的范围
-
Math:提供一些数学运算操作类!
java.lang.Math里面的功能:主要是用来数学运算
常用
public static double abs(double a):求绝对值
public static double ceil(double a):向上取整
public static double floor(double a):向下取整
public static double max(int a,int b):获取最大值
max(Math.max(10,20),50) ;方法嵌套
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 [0.0,1.0)
public static double sqrt(double a):开正平方根
-
JDK5的新特性:
自动拆装箱,静态导入,可变参数,泛型(使用居多:集合),增强for循环(使用居多)
静态导入:可以导入的方法的级别,当前这个方法必须为静态;可以导入静态的成员变量
(1)java.lang.System静态的成员变量:
public static final PrintStream out; //标准输出流 (IO----输出流的一种–>打印流)
(2)Math类:里面静态的功能
public static double abs(double d)
(3)静态导入的语法:
import static 包名.类名.(静态的成员方法名/静态的成员变量名称)
import static java.lang.System.out;//导入静态的成员变量 import static java.lang.Math.abs;//导入到静态的成员方法 import static java.lang.Math.random;//导入到静态的成员方法 /** * 注意事项: * 如果我们本是自己定义的就是abs,那么这个时候,系统无法认定是Math里面abs还是自己的abs方法(),在使用Math * 就应该写上全限定名名称 */ //import java.util.Scanner;//导入到类的级别 public class ImportStaticDemo { public static void main(String[] args) { //为了使用方便:可以优化:直接将静态的成员方法导入到这个类中, //后面再使用这个成员方法的时候直接调用即可! //静态的成员变量(同上) out.println("helloWorld"); out.println("-----------------------"); out.println(java.lang.Math.abs(-12.0)) ;//如果自己的定义冲突了,必须使用全限定名称 double random = random(); out.println("random:"+random); } //自定义的 public static double abs(double d){ return d+12.34; } }
-
集合和数组的区别?
1)长度的区别
数组:长度固定的
集合:长度可变
2)存储类型的区别
数组:既可以存储基本数据类型,也可以存储引用数据类型
集合:只能存储引用数据类型
3)存储元素的区别
数组:存储的必须都是同一种类型的元素
String[] :字符串数组 {“hello”,“world” }
举例:杯子---->可乐
集合:可以存储不同类型的元素
举例: 杯子有威士忌+可乐+冰块
Collection----后期可以通过反射的方式给Collectin添加 Integer
-
Collection
根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 集合 允许有重复的元素,而另一些则不允许。一些 集合是有序的,而另一些则是无序的。
JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和 List)实现Collection的基本功能
添加
boolean add(Object e):添加元素
删除
boolean remove(Object o):删除指定的元素
void clear():暴力删除所有元素(不推荐)
判断
boolean contains(Object o):是否包含指定的元素
boolean isEmpty():判断集合是否为空
获取功能
int size():获取集合的元素数
Iterator iterator():迭代器
Object[] toArray():将集合转换成数组
public class CollectionDemo { public static void main(String[] args) { //创建Collection集合对象:接口 //Collection c = new Collection() ;//接口不能实例化 Collection c = new ArrayList() ;//接口多态 System.out.println("c:"+c);//当前具体的子类已经重写Object类中toString //添加元素: c.add("hello") ; c.add("world") ; c.add("javaee") ; System.out.println(c); System.out.println("--------------------"); // boolean remove(Object o):删除指定的元素, System.out.println("remove():"+c.remove("javaee")); System.out.println(c); // void clear():暴力删除所有元素(不推荐) c.clear(); // boolean contains(Object o):是否包含指定的元素 System.out.println("contains():"+c.contains("高圆圆")); System.out.println("contains():"+c.contains("hello")); //boolean isEmpty():判断集合是否为空 System.out.println("isEmpty():"+c.isEmpty()); //int size():获取集合的元素数 System.out.println("size():"+c.size()); System.out.println(c); } }
-
Collection集合的高级功能
boolean addAll(Collection c):添加一个集合中的所有元素
boolean containsAll(Collection c):包含一个集合中的元素 问题:包含一个元素算包含还是所有的元素?
boolean removeAll(Collection c): 问题:删除一个算是删除还是删除所有?
boolean retainAll(Collection c):取交集:一个集合对应另一个集合取交集
问题:boolean此时表达的含义?
A集合对B集合取交集,交集的元素保存在A集合中,还是B集合中呢?
答:A集合的元素是否有变化,如果有变化,则返回true;否则,false
交集的元素保存在A集合中
public class CollectionDemo2 {
public static void main(String[] args) {
//创建两个集合
Collection c1 = new ArrayList() ;
//给c1集合中添加元素
c1.add("abc1") ;
c1.add("abc2") ;
c1.add("abc3") ;
c1.add("abc4") ;
Collection c2 = new ArrayList() ;
c2.add("abc1") ;
c2.add("abc2");
c2.add("abc3");
c2.add("abc4");
c2.add("abc5") ;
c2.add("abc6") ;
c2.add("abc7") ;
;
System.out.println("c1:"+c1);
System.out.println("c2:"+c2);
System.out.println("------------------------------");
//boolean addAll(Collection c):添加一个集合中的所有元素
//System.out.println(c1.addAll(c2));
// boolean containsAll(Collection c):包含一个集合中的元素 问题:包含一个元素算包含还是所有的元素?
//包含另一个集合中的所有元素,只要有包含关系,则返回true
//System.out.println(c1.containsAll(c2));
//boolean removeAll(Collection c): 问题:删除一个算是删除还是删除所有?
//删除一个就已经返回true:(删除另一个集合中的某一个元素)
//System.out.println(c1.removeAll(c2));
//boolean retainAll(Collection c)
System.out.println(c1.retainAll(c2));
/**
* 如果一个A集合对B集合取交集,交集的元素保存在A集合中,返回值表达的意思A集合中的元素是否发生变化
* 如果有变化,则返回true;否则是一个false
*/
System.out.println("c1:"+c1);
System.out.println("c2:"+c2);
}
}
-
集合有一个自己的专有遍历方式:迭代器
Iterator iterator():迭代器
Object next():获取下一个需要遍历的元素
boolean hasNext():迭代器接口—>提供一个判断功能:判断是否有下一个可以遍历的元素, 返回true,然后通过next方法获取
public class CollectionDemo { public static void main(String[] args) { //创建一个集合对象 Collection c = new ArrayList() ; //添加字符串元素 c.add("hello") ; c.add("world") ; c.add("javaSE") ; c.add("高圆圆") ; // Iterator iterator():迭代器 //获取Collection的迭代器 Iterator Iterator it = c.iterator(); while(it.hasNext()){ String s = (String)it.next();//返回的是Object类型,需要转型 System.out.println(s+"---"+s.length()); } } }
第三天
-
使用Collection集合存储自定义对象并遍历
两种方式
(1)Object[] toArray():将集合转换成数组
(2)Iterator iterator():获取Collection集合的迭代器
存储4个学生类型(Student) public class CollectionDemo { public static void main(String[] args) { //创建一个Collection集合对象 Collection c = new ArrayList() ; //创建4个学生 Student s1 = new Student("王宝强",38) ; Student s2 = new Student("宋喆",35) ; Student s3 = new Student("马伊琍",41); Student s4 = new Student("姚笛",34) ; //将4个学生添加到集合中 c.add(s1) ; c.add(s2) ; c.add(s3) ; c.add(s4) ; //方式1:将集合转换成数组 Object[] objs = c.toArray(); //--->Object obj = new Student() ;//多态 for(int x = 0 ; x < objs.length ; x ++){ //通过getXXX()获取学生信息 Student s = (Student)objs[x] ; System.out.println(s.getName()+"----"+s.getAge()); } System.out.println("---------------------------------------"); //方式2:获取集合的迭代器 Iterator it = c.iterator(); while(it.hasNext()){ //获取元素 it.next()--->Object //Object obj = it.next() ; //向下转型 Student s = (Student)it.next() ; System.out.println(s.getName()+"---"+s.getAge()); } } }
-
迭代器在使用过程中的注意事项:
it.next()—>Object ------>只能使用一次,使用多次出现问题
错误的: Iterator it = c.iterator(); while(it.hasNext()){ /*System.out.println(((Student)it.next()).getName()+"---"+ ((Student)it.next()).getAge());*/
-
List集合的特点:
有序性—> 存储元素和取出元素顺序一致,并且允许元素重复
List是接口------>实现类:ArrayList
-
List集合的特有功能
添加功能
void add(int index,Object element):在指定的索引处插入指定的元素(如果这个位置有
元素,向右移动)
删除功能
Object remove(int index) :删除指定位置处的元素
修改功能
Object set(int index,Object element):在指定的位置处修改(替换)指定元素
获取功能
object get(int index):返回指定索引处的元素
ListIterator listIterator():列表迭代器
-
ListIterator listIterator():列表迭代器
ListIterator:接口 extends Iterator
正向遍历:
boolean hasNext()
Object next()
逆向遍历列表 :先正向遍历,然后才能逆向遍历
boolean hasPrevious() :判断是否有上一个元素
Object previous():获取上一个元素
-
List有几种遍历方式呢?
(1)toArray()
(2)Collection的Iterator()
(3)get(int index)+size()集合:普通for
(4)List的列表迭代器ListIterator
- 创建List集合存储字符串元素,如果当前这个元素是中"world"元素,然后给集合中新添加一个"javaee"元素,然后将集合中的元素一一获取出来
出现的原因:如果使用迭代器遍历集合,就不能使用集合添加元素,因为集合添加的新元素,迭代器并不知道集合中的元素有变化就会出现这个并发修改异常
解决方案:
1)要么迭代器遍历元素,迭代器添加元素
而Collection的迭代器Iterator是没有添加功能的,只有ListIterator 列表迭代器void add(E e)具体这个功能
2)要么集合遍历元素,集合添加元素!
get(int index) +size():普通for
并发:在同一个时间点同时进行操作
-
什么是泛型?
Java提供的集合—也在模拟我们数组格式,在创建集合对象的时候,就能够明确当前集合存储的具体类型
集合的后面<引用数据类型>
Collection
List
ArrayList
<引用数据类型>:确定当前集合中存的类型
好处:
1)使用泛型,可以提高程序的安全性,解决警告问题
2)可以将运行时期的错误提前到编译时期
3)避免了强制类型转换
-
增强for的格式---->foreach语句
主要就是用来遍历集合/数组(数组一般还是使用普通for循环,防止出现问题!)
因为:增强for就是为了简化书写方式----替代迭代器!
for(数据类型 变量名: 集合对象){
输出变量名;
}
第四天
-
泛型一般用在集合居多,也可以在类上!
泛型的出现—就是给我们解决程序的安全问题,没有泛型之前,向下转型的时候可能就出现问题了!(存在安全隐患!)
-
(1)泛型定义在类上 类名<E> 名称=new 类名<E>(); (2)泛型定义在方法上 权限修饰符 <T> 返回值类型 方法名(T t){...} (3)将泛型定义在接口上,子实现类有两种情况 1)子实现类在实现接口的时候已经明确它的类型 2)子实现类在实现接口的时候不明确它的类型 <T>
-
泛型的高级通配符:了解----翻译源码或者API文档的时候,看的懂即可!
:Type 类型
:Element 元素
:Key
:Value
<?>:无边界限定符号 :Object,也可以是任意的Java类型或者自定义的类 <? extends E>:上边界限定符号: E类型以及它的子类 <? super E>:下边界限定符号:E类型以及它的父类
Map<K,V>:键值对 元素使用 泛型的时候:创建集合(使用泛型多)对象的时候,前后保持类型一致就不会有问题!
-
ArrayList集合底层是一个可变的数组实现
数组的特点:查询快,增删慢
线程是不安全的----不同步----->执行效率个高(单线程程序中只考虑效率)
当前不明确使用什么集合的时候,优先都使用ArrayList
-
Vector集合底层数据结构是一个数组,增删慢,查询快
目前线程安全的类----->同步的—安全性----执行效率低
特有功能:
添加功能:
public void addElement(E obj)
删除功能
public boolean removeElement(Object obj)
特有遍历方式
Vector中的遍历使用
public Enumeration elements():返回接口类型:向量的组件的枚举 ------ > 类似于Iterator iterator()
boolean hasMoreElements():判断是否有更多地元素----->类似于:booleanhasNext()
Object nextElement():获取元素 ---->类似于:Object next()
使用方式2遍历 :普通for
public Object elementAt(int index):获取指定位置的向量(元素)----->类似于:public Object get(int index)
public int size() :获取元素数
-
LinkedList集合底层数据结构是一个链接列表,所以查询慢,增删快
线程不安全—不同步----执行效率高
特有功能:
public void addFirst(Object e):将指定元素插入列表的开头
public void addLast(Object e):将指定的元素插入列表的末尾
public Object removeFirst():删除列表的第一个元素
public Object removeLast():删除列表的最后一个元素
public Object getFirst():获取列表第一个元素
public Object getLast():获取列表的最后一个元素
第五天
-
Set集合特点:
一个不包含重复的元素的集合 /无序性(存储和取出不一致)
Set是一个接口,不能实例化,实例化用的是具体的子实现类
HashSet(哈希表(实际上是一个 HashMap 实例)支持)
它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素
使用Set并遍历!
hash表结构:
能够保证元素唯一,每次添加元素的需要确定当前元素的哈希码值是否一样以及内容是否一样,如果都一样,只存储以前的元素!新重复的元素不会 添加到集合中!
-
HashSet集合依赖于hashMap集合,具体来说:add方法—依赖于HashMap的put方法
1)计算每一个元素的哈希码值是否一样
2)如果哈希码值一样一定是同一个内容吗?(中文存储不一定的),还需要比较内容是否相同(equals方法)才能确定是否为同一个成员信息!(自定义类必须重写Object类中的equals方法)
HashSet:底层是哈希表结构(元素唯一),不能保证元素的迭代顺序恒久不变
-
TreeSet集合
基于TreeMap集合实现的 , TreeMap(Red-black-Tree:红黑树结构---->二叉树结构)
这个集合主要的目的:对集合中存储的元素进行某种排序
这个排序—>两种
自然排序
选择器排序
取决于我们使用的构造方法
无参构造方法
public TreeSet()---->使用自然顺序排序(当前存储的元素要能够实现Comparable接口)
-
使用TreeSet集合存储自定义对象并遍历
自然排序:
学生类实现了Comparable接口:按照什么条件排序?
给出主要条件:
按照 按照学生的年龄从小到大进行排序
自己分析次要条件:
年龄一样的人,姓名一样吗? 不一定
Student类
//实现自然排序:comparable接口,重写compareTo方法
public class Student implements Comparable<Student> {
private String name ;
private int age ;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//重写
@Override
public int compareTo(Student s) { //后面存储的学生比较学生对象
// return 0; //0: 只存储1个值:里面的元素进行对比 默认的
//需要定义排序的规则
//主要条件给出: 按照学生的年龄从小到排序
//结果是一个正数:从小到大比较---->模拟Integer类中实现 comparable接口中的源码操作
int num = this.age -s.age;
//年龄一样的,不一定就是同一个人,还需要比较的姓名是否相同
int num2 = (num==0)?(this.name.compareTo(s.name)):num;
return num2 ;
}
}
测试类
public class TreeSetDemo2 {
public static void main(String[] args) {
//创建TreeSet集合对象
//空参构造
TreeSet<Student> ts = new TreeSet<Student>() ;//空参构造----->自然排序(Compareable接口)
//创建学生对象: 姓名--使用英文的 ,中文特殊(utf-8格式:一个中文对应三个字节)
Student s1 = new Student("gaoyuanyuan",41) ;
Student s2 = new Student("gaoyuanyuan",41) ;
Student s3 = new Student("gaoyuanyuan",35) ;
Student s4 = new Student("wuqilong",45) ;
Student s5 = new Student("wanglihong",38) ;
Student s6 = new Student("liushishi",38) ;
Student s7 = new Student("wenzhang",35) ;
Student s8 = new Student("zhangjia",25) ;
//java.lang.ClassCastException: com.qf_04_treeset.Student cannot be cast to java.lang.Comparable
//存储
ts.add(s1) ; //添加元素:Comparable k = new Student() ;//学生类中没有实现这个接口,不能完成自然排序
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
ts.add(s8) ;
//遍历
for(Student s:ts){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
-
TreeSet存储学生,使用选择器排序完成
主要条件:
按照学生年龄从大到小排序
TreeSet集合的有参构造方法中
public TreeSet(Comparator<? super E> comparator)
Student类 package com.qf.demo4; import java.util.Comparator; public class Student implements Comparator<Student> { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compare(Student o1, Student o2) { if(o1.age>o2.age){ return 1; }else if(o1.age<o2.age){ return -1; }else{ if(o1.name.compareTo(o2.name)>0){ return 1; }else if(o1.name.compareTo(o2.name)<0){ return -1; }else{ return 0; } } } } 测试类 package com.qf.demo4; import java.util.TreeSet; public class Test { public static void main(String[] args) { TreeSet<Student> tr=new TreeSet<>(new Student()); tr.add(new Student("zhangsan",18)); tr.add(new Student("zhangsan",18)); tr.add(new Student("lisi",18)); tr.add(new Student("lisi",20)); tr.add(new Student("wangwu",15)); tr.add(new Student("zhaoliu",28)); tr.add(new Student("dangzhangbo",24)); tr.add(new Student("zhaoliying",32)); tr.add(new Student("zhangsan",20)); for(Student s:tr){ System.out.println(s.getName()+"-----"+s.getAge()); } } }