//开发中如果是引用类型变量最好先做不为null判断
Integer iii = null;
if(iii != null) {
iii += 300; //NullPointerException
}
}
}
- 注意:在使用包装类的时候,如果是操作最好先判断是否为null;推荐只要是对象,再使用前必须进行不为null判断
1.7 日期类
1.7.1 Date类
-
导包:
java.util.Date
-
构造方法
| 方法名 | 说明 |
| — | — |
| public Date() | 创建当前系统的此刻日期时间对象 |
| public Date(long time) | 把时间毫秒值转换成日期对象 |
package ceshi;
import java.util.Date;
public class DateDemo {
public static void main(String[] args) {
//1、public Date()
Date d1 = new Date();
System.out.println(d1); //Tue Jul 06 22:36:15 CST 2021
//2、public Date(long time)
long date = 60;
Date d2 = new Date(date);
System.out.println(d2); //Thu Jan 01 08:00:00 CST 1970
}
}
- 常用方法
| 方法名 | 说明 |
| — | — |
| public long getTime() | 获取日期对象从1970年1月1日00:00:00 到现在的毫秒值 |
| public void setTime(long time) | 设置时间,给的是毫秒值 |
package ceshi;
import java.util.Date;
public class DateDemo {
public static void main(String[] args) {
//1、public long getTime() 获取日期对象从1970年1月1日00:00:00 到现在的毫秒值
Date d = new Date();
System.out.println(d.getTime()); //1625582796041
//2、public void setTime(long time) 设置时间,给的是毫秒值
long time = 10006060;
d.setTime(time);
System.out.println(d); //Thu Jan 01 09:00:00 CST 1970
}
}
1.7.2 SimpleDateFormat类 [ˈsɪmpl]
-
可以对日期格式化和解析
-
日期和时间格式由日期和时间模式字符串指定,在日期和时间模式字符串中,从 ‘A’ 到 ‘Z’ 以及从 ‘a’ 到’z’ 引号的字母被解释为表示日期或时间字符串的组件的模式字母
-
常用的模式字母对应: y—年;M—月;d—日;H—时;m—分;s—秒;E—星期几;a—上午 / 下午
-
构造方法:
| 方法名 | 说明 |
| — | — |
| public SimpleDateFormat() | 使用默认模式和日期模式 |
| public SimpleDateFormat(String pattern) | 指定时间的格式创建简单日期格式化对象 |
- 格式化和解析日期方法
| 方法名 | 说明 |
| — | — |
| public String format(Date date) | 将日期格式化为日期 / 时间字符串 |
| public String format(Object time) | 将时间毫秒格式化为日期 / 时间字符串 |
| public Date parse(String source) [pɑːz] | 从给定的字符串开始解析文本生成日期 |
package ceshi;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatDemo {
public static void main(String[] args) throws ParseException {
//格式化 Date》String
Date d = new Date();
//1、 SimpleDateFormat sdf = new SimpleDateFormat(); //无参构造
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy年MM月dd日 HH:mm:ss E a”); //2、带参构造
String s = sdf.format(d);
System.out.println(s); //1、21-7-11 上午10:13 2、2021年07月11日 10:16:00 星期日 上午
//解析 String > date
String s1 = “2020年1月1日 8:25:12”;
SimpleDateFormat sdf1 = new SimpleDateFormat(“yyyy年MM月dd日 HH:mm:ss”);
Date d1 = sdf1.parse(s1); //parse报错了,选中按下Alt+enter,默认选第一个
System.out.println(d1); //Wed Jan 01 08:25:12 CST 2020
}
}
1.7.3 日期工具类
package ceshi;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
工具类
构造方法私有
成员方法静态
*/
public class DateUtils {
private DateUtils() {
}
//时间对象格式化
public static String dateToString(Date date, String format) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
String s = sdf.format(date);
return s;
}
//给定日期字符串解析为时间对象
public static Date stringDate(String s,String formart) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(formart);
Date d = sdf.parse(s);
return d;
}
}
package ceshi;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateDemo {
public static void main(String[] args) throws ParseException {
Date d = new Date();
String s = DateUtils.dateToString(d, “yyyy年MM月dd日 HH:mm:ss”);
System.out.println(s); //2021年07月07日 20:46:08
String s1 = “2022年12月5日”;
Date d1 = DateUtils.stringDate(s1, “yyyy年MM月dd日”);
System.out.println(d1); //Mon Dec 05 00:00:00 CST 2022
}
}
1.7.4 Calendar日历类
-
Calendar 代表了系统此刻日期对应的日历对象
-
Calendar 是一个抽象类,不能直接创建对象
-
常用方法
| 方法名 | 说明 |
| — | — |
| public static Calendar getInstance() | 返回一个日历类的对象 |
| public int get(int field) | 返回给定日历的值 |
| public void set(int field,int value) | 修改日历的某个字段信息 |
| public abstract void add(int field,int amount) | 根据日历的规则,将指定的时间量添加或减去给定的日历字段 |
| public final void set(int year,int month,int date) | 设置当前日历年月日 |
package ceshi;
import java.util.Calendar;
public class CalendarDemo {
public static void main(String[] args) {
//1、获取Calendar对象
Calendar c = Calendar.getInstance(); //多态形式
//2、public int get (int field) 根据给的日历字段返回值
/* int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1; //从0开始所以加个1
int date = c.get(Calendar.DATE);
System.out.println(year+“年”+month+“月”+date+“日”); //2021年7月7日*/
//3、public void set(int field,int value) 修改日历的某个字段信息
//c.set(Calendar.YEAR,2099);
// System.out.println(rightNow.get(Calendar.YEAR)); //2099
//4、public abstract void add(int field,int amount):根据日历的规则,将指定的时间量添加或减去给定的日历字段
//需求1:三年前
/* c.add(Calendar.YEAR,-3);
int year = c.get(Calendar.YEAR);
System.out.println(year); //2018,减了三年*/
//需求2:十年后,五天前
/*c.add(Calendar.YEAR,10);
c.add(Calendar.DATE,-5);
System.out.println();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1;
int date = c.get(Calendar.DATE);
System.out.println(year+“年”+month+“月”+date+“日”); //2031年7月2日*/
//5、public final void set(int year,int month,int date):设置当前日历年月日
c.set(2022,1,1);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1;
int date = c.get(Calendar.DATE);
System.out.println(year+“年”+month+“月”+date+“日”); //2022年2月1日
}
}
2.1 String概括
-
String 类 在java.lang包下,所以使用的时候不需要导包
-
java程序中所有的双引号字符串,都是String这个类的对象
-
特点:字符串不可变,它们的值在创建后不可改变
2.2 String构造方法
| 方法名 | 说明 |
| — | — |
| public String() | 创建一个空字符串对象,不包含任何内容 |
| public String(chas[] chs) | 根据字符数组内容,来创建字符串对象 |
| public String(byte[] bys) | 根据字节数组内容,来创建字符串对象 |
| String s = “abc”; | 直接赋值的方法创建字符串对象,内容就是abc |
-
推荐使用直接赋值的方式
-
案例:
public class Demo{
public static void main(String[] args){
//1.public String() 创建一个空字符串对象,不包含任何内容
String s1 = new String();
System.out.println(“s1:”+s1); //s1:(无内容)
//2.public String(chas[] chs) 根据字符数组内容,来创建字符串对象
char[] chs = {‘a’,‘b’,‘c’};
String s2 = new String(chs);
System.out.println(“s2:”+s2); //s2:abc
//3.public String(byte[] bys) 根据字节数组内容,来创建字符串对象
byte[] bys = {97,98,99}; //对应计算机底层字符
String s3 = new String(bys);
System.out.println(“s3:”+s3); //s3:abc
//4.String s = “abc”; 直接赋值的方法创建字符串对象,内容就是abc
String s4 = “abc”;
System.out.println(“s4:”+s4); //s4:abc
}
}
2.3 String对象的区别
- 1.通过 new 创建字符串对象,每一次 new 都会申请一个内存空间,虽然内容相同,但是地址值不同
- 2.以 “ ” 方式给出的字符串,只要字符串的序列相同(顺序和大小写),无论在程序中出现多少次,JVM都只会建立一个String对象,并在字符串池维护
- 内存
2.4 常考面试题
- 问题1:
- 问题2:
- 问题3:
- 问题4:
2.5 String字符串比较
-
使用双等号作比较
-
基本类型:比较的是数据值是否相同
-
引用类型:比较的是地址值是否相同
-
字符串是对象,它比较内容是否相同,是通过一个方法来实现的,这个方法叫做: equals()
-
范例:
public class Demo{
public static void main(String[] args){
//构造方法的方式得到对象
char[] chs = {‘a’,‘b’,‘c’};
String s1 = new String(chs);
String s2 = new String(chs);
//直接赋值的方法得到对象
String s3 = “abc”;
String s4 = “abc”;
System.out.println(s1.equals(s2)); //true
System.out.println(s1.equals(s3)); //true
System.out.println(s3.equals(s4)); //true
}
}
2.6 案例
2.6.1 案例:用户登录
import java.util.Scanner;
public class Demo{
public static void main(String[] args){
//1
String username = “YM”;
String password = “123456”;
Scanner sc = new Scanner(System.in);
//4
for(int i=1;i<=3;i++) {
//2
System.out.println(“请输入用户名”);
String name = sc.nextLine();
System.out.println(“请输入密码”);
String pwd = sc.nextLine();
//3
if(name.equals(username)&& pwd.equals(password)) {
System.out.println(“登录成功”);
break;
}else {
if (3-i==0){
System.out.println(“你的账户被锁定”);
}else {
System.out.println(“登陆失败,你还有”+(3-i)+“次机会”);
}
}
}
}
}
2.6.2 案例:遍历字符串
import java.util.Scanner;
public class Demo{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println(“请输入一个字符串”);
String line = sc.nextLine();
for(int i=0;i<line.length();i++) { //length():获取字符串长度
System.out.println(line.charAt(i));
}
}
}
9.2.6.3 案例:统计字符次数
import java.util.Scanner;
public class Demo{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println(“请输入一个字符”);
String line = sc.nextLine();
int bigCount = 0;
int smallCount = 0;
int numberCount = 0;
//遍历字符串,得到每个字符
for(int i=0;i<line.length();i++) {
char ch = line.charAt(i);
//判断字符类型,统计变量+1
if(ch>=‘A’ && ch<=‘Z’){
bigCount++;
}else if(ch>=‘a’ && ch<=‘z’){
smallCount++;
}else if(ch>=‘0’ && ch<=‘9’){
numberCount++;
}
}
System.out.println(“大写字母:”+bigCount+“个”);
System.out.println(“小写字母:”+smallCount+“个”);
System.out.println(“数字:”+numberCount+“个”);
}
}
2.6.4 案例:字符串拼接
public class Demo {
public static void main(String[] args) {
int[] arr = {1,2,3};
String s = arrayToString(arr);
System.out.println(s); //[1, 2, 3]
}
public static String arrayToString(int[] arr) {
String s = “”;
s += “[”;
for(int i=0;i<arr.length;i++) {
if(i== arr.length-1) {
s += arr[i];
}else {
s += arr[i]+", ";
}
}
s += “]”;
return s;
}
}
2.6.5 案例:字符串反转
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(“请输入一个字符串”);
String line = sc.nextLine(); //abc
String s = myReverse(line);
System.out.println(s); //cba
}
public static String myReverse(String s) {
String ss = “”;
for(int i=s.length()-1;i>=0;i–) {
ss += s.charAt(i);
}
return ss;
}
}
2.6.6 案例:字符串截取
public class Demo {
/*
截取字符串:
String substring(int beginIndex):
从传入的索引位置处向后截取,一直截取到末尾,得到新字符串并返回
String substring(int beginIndex, int endIndex):
从beginIndex索引位置开始截取,截取到endIndex索引位置,得到新字符串并返回(包括头,不包括尾)
*/
public static void main(String[] args){
String s = “itheima”;
String ss = s.substring(2);
System.out.println(ss); //heima
String sss = s.substring(0,2);
System.out.println(sss); //it
}
}
2.6.7 案例:字符串替换
//String replace(CharSequence target,Char Sequense replacement)
// 第一个参数为target(被替换的旧值)内容
// 第二个参数为replacement(替换的新值)进行替换
// 返回新的字符串
import java.util.Scanner
public class Demo{
public static void main(String[] args){
// 1.键盘录入一个字符串
Scanner sc = new Scanner(System.in);
System.out.println(“请输入:”);
String s = sc.nextLine();
// 2.进行敏感提替换
String result = s.replace(“TMD”,“***”);
// 3.输出结果
System.out.println(result);
}
}
- StringBuilder是一个可变的字符串类,内容可以改变
3.1 StringBuilder构造方法
- 范例
public class Demo {
public static void main(String[] args) {
//创建空白可改变字符串对象
StringBuilder sb = new StringBuilder();
System.out.println(“sb:”+sb); //sb:
System.out.println(“sb.length():”+sb.length()); //sb.length():0
//根据字符串内容创建对象
StringBuilder sb2 = new StringBuilder(“hello”);
System.out.println(“sb2:”+sb2); //sb2:hello
System.out.println(“sb2.length():”+sb2.length()); //5
}
}
3.2 StringBuilder常用方法
| 方法名 | 说明 |
| — | — |
| public StringBuilder append(任意类型) | 添加数据,并返回对象本身 |
| public StringBuilder reverse() | 返回相反的字符序列 |
| public int length() | 返回长度(字符出现的个数) |
- 范例:
public class Demo {
public static void main(String[] args) {
//创建对象
StringBuilder sb = new StringBuilder();
//1.public StringBuilder append(任意类型) 添加数据,并返回对象本身
// StringBuilder sb2 = sb.append(“java”);
// System.out.println(“sb:”+sb); //sb:java,因为返回的是对象本身所以sb赋值了java
// System.out.println(“sb2:”+sb2); //sb2:java
// System.out.println(sb==sb2); //true
// sb.append(“java”);
// sb.append(“word”);
// sb.append(100);
// System.out.println(“sb:”+sb); //sb:javaword100
//链式编程
sb.append(“java”).append(“word”).append(100);
System.out.println(“sb:”+sb); //sb:javaword100
//2.public StringBuilder reverse() 返回相反的字符序列
sb.reverse();
System.out.println(“sb:”+sb); //sb:001drowavaj
}
}
3.3 StringBuilder 和 String 相互转换
- 1.StringBuilder 转换为 String
| public String toString() | 通过toString()可以把StringBuilder 转换为 String |
| — | — |
- 2.String 转换为 StringBuilder
| public StringBuilder(String s) | 通过构造方法就可以把String 转换为 StringBuilder |
| — | — |
- 范例
public class Demo {
public static void main(String[] args) {
//1.StringBulider 转换为 String
StringBuilder sb = new StringBuilder();
sb.append(“hello”);
//public String toString() 通过toString()可以把StringBuilder 转换为 String
String s = sb.toString();
System.out.println(“s:”+s); //s:hello
//2.String 转换为 StringBulider
String s1 = “hello”;
//public StringBuilder(String s) 通过构造方法就可以把String 转换为 StringBuilder
StringBuilder sb1 = new StringBuilder(s1);
System.out.println(“sb1:”+sb1); //sb1:hello
}
}
3.4 案例
3.4.1 案例1:拼接字符串
public class Demo {
public static void main(String[] args) {
//1
int[] arr = {1,2,3};
String s = arrayToString(arr);
System.out.println(s); //[1, 2, 3]
}
//2,定义方法,拼接字符串
public static String arrayToString(int[] arr) {
//3
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for(int i=0;i< arr.length;i++) {
if(i==arr.length-1){
sb.append(arr[i]);
}else {
sb.append(arr[i]).append(", ");
}
}
sb.append(“]”);
String s= sb.toString();
return s;
}
}
3.4.2 案例2:字符串反转
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(“请输入一个字符串”);
String line = sc.nextLine(); //abc
String s = myReverse(line);
System.out.println(s); //cba
}
public static String myReverse(String s) {
//在方法使用StringBuilder实现字符串反转,并把结果转换为String返回
//String - StringBuilder - reverse() - String
// StringBuilder sb = new StringBuilder(s);
// sb.reverse();
//
// String ss = sb.toString();
// return ss;
//链式编程
return new StringBuilder(s).reverse().toString();
}
}
-
集合提供一种存储空间可变的存储模型,存储的数据容量可以改变
-
ArrayLis<>:
-
可调整大小的数组实现
-
<>:是一种特殊的数据类型,泛型
-
可储存重复元素
-
怎么使用呢
-
在出现E的地方我们使用引用数据类型替换即可
-
举例:
ArrayList<String>、ArrayList<Student>
4.1 集合与数组的区别
-
共同点:都是存储数据的容器
-
不同点:数组的容量是固定的,集合的容量是可变的
4.2 ArrayList 构造方法和添加方法
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
//创建集合对象
ArrayList array = new ArrayList<>();
System.out.println(array); //[]
//添加到集合末尾
array.add(“hello”);
array.add(“word”);
array.add(“java”);
System.out.println(array); //[hello, word, java]
//指定位置,添加元素
array.add(1,“javase”);
System.out.println(array); //[hello, javase, word, java]
array.add(4,“javaee”);
System.out.println(array); //[hello, javase, word, java, javaee]
array.add(6,“javaweb”);
System.out.println(array); //IndexOutOfBoundsException,不能中间跳一个位置
}
}
4.3 ArrayList 常用方法
| 方法名 | 说明 |
| — | — |
| public boolean remove(Object o) | 删除指定的元素,返回删除是否成功 |
| public E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
| public E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
| public E get(int index) | 返回指定索引处的元素 |
| public int size() | 返回集合中元素的个数 |
- 范例:
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
//创建集合对象
ArrayList array = new ArrayList<>();
System.out.println(array); //[]
//添加到集合末尾
array.add(“hello”);
array.add(“word”);
array.add(“java”);
System.out.println(array); //[hello, word, java]
//1,public boolean remove(Object o) 删除指定的元素,返回删除是否成功
// System.out.println(array.remove(“hello”)); //true; 集合变为[word, java]
// System.out.println(array.remove(“javase”)); //false; 集合变为[hello, word, java]
//2,public E remove(int index) 删除指定索引处的元素,返回被删除的元素
// System.out.println(array.remove(1)); //word,集合变为[hello, java]
//3,public E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
// System.out.println(array.set(1,“javase”)); //word;集合变为[hello, javase, java]
//4,public E get(int index) 返回指定索引处的元素
// System.out.println(array.get(0)); //hello
// System.out.println(array.get(1)); //word
// System.out.println(array.get(2)); //java
//5,public int size() 返回集合中元素的个数
System.out.println(array.size()); //3
}
}
4.4 案例
4.4.1 案例1:存储字符串并遍历
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
//创建集合对象
ArrayList array = new ArrayList<>();
//加元素
array.add(“java”);
array.add(“天下”);
array.add(“第一”);
for(int i=0;i<array.size();i++) {
String s = array.get(i);
System.out.print(s+" "); //java 天下 第一
}
}
}
4.4.2 案例2:存储学生对象并遍历
- Student类
package ceshi;
public class 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;
}
}
- 测试类
package ceshi;
import java.util.ArrayList;
public class ArrayListStudent {
public static void main(String[] args) {
//定义集合对象
ArrayList array = new ArrayList();
//创建学生对象
Student stu1 = new Student(“小白”,20);
Student stu2 = new Student(“小明”,21);
Student stu3 = new Student(“小黑”,22);
//添加学生对象到集合中
array.add(stu1);
array.add(stu2);
array.add(stu3);
//遍历集合
for(int i=0;i<array.size();i++) {
Student s = array.get(i);
System.out.println(s.getName()+“,”+s.getAge()); //小白,20
//小明,21
//小黑,22
}
}
}
4.4.3 案例3:存储学生对象并遍历升级版
- 测试类
package ceshi;
import java.util.ArrayList;
import java.util.Scanner;
public class ArrayListStudent {
public static void main(String[] args) {
ArrayList array = new ArrayList();
for(int i=1;i<4;i++) {
addStudent(array); //调三次方法
}
//遍历集合
for(int i=0;i<array.size();i++) {
Student s = array.get(i);
System.out.println(s.getName()+“,”+s.getAge());
}
}
public static void addStudent(ArrayList array) {
Scanner sc = new Scanner(System.in);
System.out.println(“请输入一个名字”);
String name = sc.nextLine();
System.out.println(“请输入一个年龄”);
String age = sc.nextLine();
//创建学生对象,把键盘录入的数据赋值给学生对象的成员变量
Student stu = new Student();
stu.setName(name);
stu.setAge(age);
//往集合里加学生对象
array.add(stu);
}
}
5.1 Collection集合概述
-
是单列集合的顶层接口,它表示一组对象,这些对象也称Collection元素
-
JDK不提供此接口的直接实现,它提供更具体的子接口(Set 和 List)实现
package ceshi;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
//创建Collection集合对象
Collection c = new ArrayList();
//添加元素
c.add(“hello”);
c.add(“world”);
c.add(“java”);
System.out.println©; //[hello, world, java]
}
}
5.2 Collection集合常用方法(查看所有源码快捷键)
| 方法名 | 说明 |
| — | — |
| public boolean add(E e) | 把给定的元素添加到当前集合中 |
| public boolean remove(E e) | 把给定的对象在当前集合中删除 |
| public void clear() | 清空集合中所有的元素 |
| public boolean contains(Object obj) [kənˈteɪnz] 包括 | 判断当前集合中是否存在指定的对象 |
| public boolean isEmpty() [ˈenpti] | 判断当前集合是否为空 |
| public int size() | 返回集合中元素的个数 |
| public Object[] toArray( ) | 把集合中的元素,储存到数组中 |
- 快捷键:Alt+7 打开源码中所有方法
package ceshi;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
//创建Collection集合对象
Collection c = new ArrayList();
//1、public boolean add(E e) 把给定的元素添加到当前集合中
c.add(“hello”);
c.add(“hello”);
System.out.println©; //[hello, hello] ;ArrayList可以存储重复元素
//2、public boolean remove(E e) 把给定的对象在当前集合中删除
/*System.out.println(c.remove(“hello”)); //true
System.out.println(c.remove(“java”)); //false
System.out.println©; //[hello]*/
//3、public void clear() 清空集合中所有的元素
/*c.clear();
System.out.println©; //[]*/
//4、public boolean contains(Object obj) 判断当前集合中是否存在指定的对象
/*System.out.println(c.contains(“java”)); //false
System.out.println(c.contains(“hello”)); //true*/
//5、public boolean isEmpty() 判断当前集合是否为空
// System.out.println(c.isEmpty()); //false
//6、public int size() 返回集合中元素的个数
// System.out.println(c.size()); //2
//7、public Object[] toArray( 把集合中的元素,储存到数组中
Object[] arr = c.toArray();
for(int i= 0;i< arr.length;i++) {
System.out.print(arr[i]+“,”); //hello,hello
}
}
}
5.3 Collection集合的遍历
-
Collection 集合遍历有三种方法:
-
迭代器
-
foreach(增强for循环)
-
DK 1.8 开始的新技术 Lambda 表达式(了解)
5.3.1 Iterator['lɪtəreɪtə]迭代器遍历集合
-
lterator:迭代器,集合的专用遍历方式
-
Iterator<E> iterator()
:返回此集合中元素的迭代器,通过集合的iterator()
方法得到 -
迭代器是通过集合的**iterator()**方法得到的,所以我们说它是依赖于集合而存在的
-
Iterator中的常用方法
| 方法名 | 说明 |
| — | — |
| E next() | 获取迭代中的下一个元素 |
| boolean hasNext() | 如果迭代具有更多元素,则返回true |
package ceshi;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class IteratorDemo {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(“java”);
c.add(“天下”);
c.add(“无敌”);
//Iterator iterator():返回此集合中元素的迭代器,通过集合的iterator0方法得到
Iterator it = c.iterator(); //c.iterator();按下Ctrl+alt+v
/*public Iterator iterator() {
return new ArrayList.Itr(); //返回的是实现类的对象
}
private class Itr implements Iterator {…}
*/
//E next()
/*System.out.println(it.next()); //java
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next()); //NoSuchElementException:表示请求的元素不存在*/
//boolean hasNext() 如果迭代具有更多元素,则返回true
/*if(it.hasNext()) {
System.out.println(it.next()); //java
}
if(it.hasNext()) {
System.out.println(it.next()); //天下
}
if(it.hasNext()) {
System.out.println(it.next()); //无敌
}
if(it.hasNext()) {
System.out.println(it.next()); //无输出
} */
//while循环改良
while(it.hasNext()) {
String s = it.next();
System.out.println(s); //java
//天下
//无敌
}
}
}
- 案例
package ceshi;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String[] args) {
//2、创建Collection集合对象
Collection c = new ArrayList();
//3、创建学生对象
Student s1 = new Student(“y1”, 10);
Student s2 = new Student(“y2”, 20);
Student s3 = new Student(“y3”, 30);
//4、把学生添加到集合
c.add(s1);
c.add(s2);
c.add(s3);
//5、遍历集合
Iterator it = c.iterator(); //必须集合添加完毕后创建迭代器对象
while (it.hasNext()) {
Student s = it.next();
System.out.println(s.getName() + “,” + s.getAge());
/*
y1,10
y2,20
y3,30
*/
}
}
}
5.4 Collections工具类
-
包:
java.util.Collections
-
Collections 并不属于集合,而是用来操作集合的工具类
-
常用方法(全是静态修饰,用类名调用)
| 方法名 | 说明 |
| — | — |
| public static <T extends Comparable<?super T>> void sort(List list) | 将指定的列表按升序排序 |
| public static void reverse(List<?> list) | 反转指定列表中元素顺序 |
| public static void shuffle(List<?> list) | 使用默认的随机源随机排序指定的列表 |
package ceshi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MapDemo {
public static void main(String[] args) {
List list = new ArrayList<>();
list.add(30);
list.add(20);
list.add(50);
list.add(10);
list.add(40);
System.out.println(list); //[30, 20, 50, 10, 40]
//1,public static <T extends Comparable<?super T>> void sort(List list) 将指定的列表按升序排序
/*Collections.sort(list);
System.out.println(list); //[10, 20, 30, 40, 50]*/
//2,public static void reverse(List<?> list) 反转指定列表中元素顺序
/*Collections.reverse(list);
System.out.println(list); //[40, 10, 50, 20, 30]*/
//3,public static void shuffle(List<?> list) 使用默认的随机源随机排序指定的列表
Collections.shuffle(list);
System.out.println(list);
//第一次运行[10, 40, 30, 50, 20]
//第二次运行[10, 30, 20, 50, 40]
}
}
-
List系列集合:添加的元素是有序,可重复,有索引
-
ArrayList: 添加的元素是有序,可重复,有索引
-
LinkedList: 添加的元素是有序,可重复,有索引
-
Vector :是线程安全的,速度慢,开发中很少使用
6.1 List集合概述和特点
List集合概述
1、有序集合(也称为序列),用户可以精确控制列表中每个元索的插入位置。用户可以通过整数索引访问元素,并获取列表中的元素
2、与Set集合不同,List集合允许重复的元素
List集合特点
1、有序: 存储和取出的元素顺序一致
2、可重复: 存储的元素可以重复
package ceshi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//创建集合对象
List list = new ArrayList<>();
//添加元素
list.add(“java”);
list.add(“天下”);
list.add(“无敌”);
list.add(“java”);
System.out.println(list); //[java, 天下, 无敌, java]
//迭代器遍历
Iterator it = list.iterator();
while(it.hasNext()) {
String s = it.next();
System.out.println(s);
/*java
天下
无敌
java*/
}
}
}
6.2 List集合的特有方法
| 方法名 | 说明 |
| — | — |
| public void add(int index,E element) | 该集合中的指定位置上插入元素 |
| public E remove(int index) | 删除列表中指定位置的元素,返回被删除的元素 |
| public E set(int index,E element) | 修改指定索引的元素,返回被修改的元素 |
| public E get(int index) | 返回集合中指定位置的元素 |
package ceshi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//创建集合对象
List list = new ArrayList<>();
//添加元素
list.add(“java”);
list.add(“天下”);
list.add(“无敌”);
list.add(“java”);
System.out.println(list); //[java, 天下, 无敌, java]
//1、public void add(int index,E element) 该集合中的指定位置上插入元素
list.add(1,“javase”);
System.out.println(list); //[java, javase, 天下, 无敌, java]
//2、public E remove(int index) 删除列表中指定位置的元素,返回被删除的元素
System.out.println(list.remove(1)); //javase
System.out.println(list); //[java, 天下, 无敌, java]
//3、public E set(int index,E element) 修改指定索引的元素,返回被修改的元素
System.out.println(list.set(0,“java1”)); //java
System.out.println(list); //[java1, 天下, 无敌, java]
//4、public E get(int index) 返回集合中指定位置的元素
System.out.println(list.get(2)); //无敌
//for循环遍历
for(int i=0;i< list.size();i++) {
//5,public E get(int index) 返回集合中指定位置的元素
String s = list.get(i);
System.out.println(s);
/*java1
天下
无敌
java*/
}
}
}
- 案例
- 测试类
package ceshi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//2、创建集合对象
List list = new ArrayList();
//3、创建学生对象
Student s1 = new Student(“y1”,10);
Student s2 = new Student(“y2”,20);
Student s3 = new Student(“y3”,30);
//4、学生对象添加到集合
list.add(s1);
list.add(s2);
list.add(s3);
//5、遍历集合:迭代器方法
Iterator it = list.iterator();
while(it.hasNext()) {
Student s = it.next();
System.out.println(s.getName()+“,”+s.getAge());
/*y1,10
y2,20
y3,30*/
}
//5、遍历集合:for循环
for(int i=0;i<list.size();i++) {
Student ss = list.get(i);
System.out.println(ss.getName()+“,”+ss.getAge());
/*y1,10
y2,20
y3,30*/
}
}
}
6.3 ListIterator迭代器
-
Lstlterator:列表迭代器
-
通过List集合的
listterator()
方法得到,所以说它是List集合特有的迭代器 -
用于允许程序员沿任一方向遍历列表的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
-
常用方法
| 方法名 | 说明 |
| — | — |
| list.listIterator() | 得到 listIterator 迭代器 |
| E next() | 返回迭代中的下一个元素 |
| boolean hasNext() | 如果迭代具有更多元素,则返回true |
| E previous() [ˈpriːviəs] | 返回列表中的上一个元素 |
| boolean hasPrevious() | 如果此列表迭代器在相反方向遍历列表时具有更多元索,则返回true |
| void add(E e) | 将指定的元索插入列表 |
package ceshi;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorDemo {
public static void main(String[] args) {
List list = new ArrayList<>();
list.add(“java”);
list.add(“python”);
list.add(“scala”);
//通过list集合的listIterator() 方法得到迭代器
/*ListIterator lit = list.listIterator();
while(lit.hasNext()) {
String s = lit.next();
System.out.println(s);
*//*java
python
scala*//*
}
System.out.println(“---------”);
//逆向遍历
*//*E previous0 返回列表中的上一个元素
boolean hasPrevious() 如果此列表迭代器在相反方向遍历列表时具有更多元索,则返回true*//*
while(lit.hasPrevious()) {
String s = lit.previous();
System.out.println(s);
*//*scala
python
java*//*
}*/
//获取列表迭代器
ListIterator lit = list.listIterator();
while(lit.hasNext()) {
String s = lit.next();
if(s.equals(“java”)) {
lit.add(“world”);
}
}
System.out.println(list); //[java, world, python, scala]
}
}
6.4 foreach(增强for循环)
增强for:简化数组和Collection集合的遍历
-
实现Iterable接口的类允许其对象成为增强型 for语句的目标
-
它是JDK5之后出现的,其内部原理是一个Iterator迭代器
-
格式
for(元素类型 变量名: 数组名或collection集合){
}
//范例
int[] arr = {1,2,3,4,5};
for(int i : arr) {
System.out.println(i);
}
- 范例:
package ceshi;
import java.util.ArrayList;
import java.util.List;
public class ForDemo {
public static void main(String[] args) {
//int类型数组
int[] arr = {1,2,3,4,5};
for(int i : arr) {
System.out.println(i);
/*
1
2
3
4
5*/
}
//String类型数组
String[] strArray = {“java”,“python”,“scala”};
for(String s : strArray) {
System.out.println(s);
/*java
python
scala*/
}
//集合
List list = new ArrayList<>();
list.add(“y1”);
list.add(“y2”);
list.add(“y3”);
for(String lt:list) {
System.out.println(lt);
/*y1
y2
y3*/
}
//判断:内部原理是一个Iterator迭代器
for(String s:list) {
if(s.equals(“y1”)) {
list.add(“y4”); //ConcurrentModificationException:并发修改异常
}
}
}
}
6.5 案例:List集合存储学生对象用三种方式遍历
- 测试类
package ceshi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
List list = new ArrayList<>();
Student s1 = new Student(“y1”,10);
Student s2 = new Student(“y2”,20);
Student s3 = new Student(“y3”,30);
list.add(s1);
list.add(s2);
list.add(s3);
//迭代器方式
Iterator it = list.iterator();
while(it.hasNext()) {
Student s = it.next();
System.out.println(s.getName()+“,”+s.getAge());
}
System.out.println(“----------”);
//for带索引方式
for(int i =0;i<list.size();i++) {
Student s = list.get(i);
System.out.println(s.getName()+“,”+s.getAge());
}
System.out.println(“----------”);
//增强for
for(Student s: list) {
System.out.println(s.getName()+“,”+s.getAge());
}
}
}
6.6 List集合子类特点
-
ArrayList
:底层数据结构数组实现,查询快,增删慢 -
LinkedList
:底层数据结构链表实现,查询慢,增删快 -
范例:分别用ArrayList和LinkedList存储字符串并遍历
package ceshi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//1、创建ArrayList集合对象
ArrayList arraylist = new ArrayList<>();
arraylist.add(“java”);
arraylist.add(“python”);
arraylist.add(“scala”);
//增强for
for(String s: arraylist) {
System.out.println(s);
}
System.out.println(“-------”);
//普通for循环
for(int i=0;i< arraylist.size();i++) {
String s = arraylist.get(i);
System.out.println(s);
}
System.out.println(“-------”);
//迭代器的方式
Iterator it = arraylist.iterator();
while(it.hasNext()) {
String s = it.next();
System.out.println(s);
}
System.out.println(“-------”);
//2、创建LinkedList集合对象
LinkedList linkedList = new LinkedList<>();
linkedList.add(“a”);
linkedList.add(“b”);
linkedList.add(“c”);
//增强for
for(String s:linkedList) {
System.out.println(s);
}
System.out.println(“-------”);
//普通for
for(int i=0;i< linkedList.size();i++) {
String s = linkedList.get(i);
System.out.println(s);
}
System.out.println(“-------”);
//迭代器
Iterator it1 = linkedList.iterator();
while(it1.hasNext()) {
String s = it1.next();
System.out.println(s);
}
}
}
6.7 LinkedList集合特有方法
| 方法名 | 说明 |
| — | — |
| public void addFirst(E,e) | 在该列表开头插入指定的元素 |
| public void addLast(E,e) | 将指定的元索追加到此列表的末尾 |
| public E getFirst() | 返回此列表中的第一个元索 |
| public E getLast() | 返回此列表中的最后一个元素 |
| public E removeFirst | 从此列表中删除并返回第一个元素 |
| public E removeLast | 从此列表中删除并返回最后一个元素 |
package ceshi;
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) {
//创建集合对象
LinkedList linkedList = new LinkedList<>();
linkedList.add(“java”);
linkedList.add(“python”);
linkedList.add(“scala”);
System.out.println(linkedList); //[java, python, scala]
//1、public void addFirst(E,e) 在该列表开头插入指定的元素
linkedList.addFirst(“1”);
System.out.println(linkedList); //[1, java, python, scala]
//2、public void addLast(E,e) 将指定的元索追加到此列表的末尾
linkedList.addLast(“5”);
System.out.println(linkedList); //[1, java, python, scala, 5]
//3、public E getFirst() 返回此列表中的第一个元索
System.out.println(linkedList.getFirst()); //1
//4、public E getLast() 返回此列表中的最后一个元素
System.out.println(linkedList.getLast()); //5
//5、public E removeFirst 从此列表中删除并返回第一个元素
System.out.println(linkedList.removeFirst()); //1
System.out.println(linkedList);//[java, python, scala, 5]
//6、public E removeLast 从此列表中删除并返回最后一个元素
System.out.println(linkedList.removeLast()); //5
System.out.println(linkedList); //[java, python, scala]
}
}
7.1 Set集合的概述和特点
-
Set集合的特点
-
不包含重复元素的集合
-
没有带索引的方法,所以不能使用普通for循环
-
Set集合是接口通过实现类实例化(多态的形式)
-
HashSet
:添加的元素是无序,不重复,无索引的 -
LinkedHashSet
: 添加的元素是有序,不重复,无索引的 -
TreeSet
: 不重复,无索引,按照大小默认升序排列
package ceshi;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
//创建Set集合对象
Set set = new HashSet<>();
//添加元素
set.add(“java”);
set.add(“python”);
set.add(“scala”);
//不包含重复元素
set.add(“java”);
//两种遍历方式
for(String s:set) {
System.out.println(s);
/*python
java
scala*/
}
System.out.println(“--------”);
Iterator it = set.iterator();
while(it.hasNext()) {
String s = it.next();
System.out.println(s);
/*python
java
scala*/
}
}
}
7.2 哈希值
-
哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
-
Object类中有一个方法可以获取对象的哈希值
public int hashCode()
:返回对象的哈希码值
-
对象的哈希值特点
-
同一个对象多次调用hashCode()方法返回的哈希值是相同的
-
默认情况下,不同对象的哈希值是不同的。而重写hashCode0方法,可以实现让不同对象的哈希值相同
package ceshi;
public class HashDemo {
public static void main(String[] args) {
//创建学生对象
Student s1 = new Student(“y1”,10);
//同一个对象多次调用hashCode()方法哈希值相同
System.out.println(s1.hashCode()); //460141958
System.out.println(s1.hashCode()); //460141958
System.out.println(“---------”);
//默认情况下,不同对象哈希值不同;重写hashCode()方法就可以使哈希值相同
Student s2 = new Student(“y2”,20);
System.out.println(s2.hashCode()); //1163157884
System.out.println(“---------”);
System.out.println(“java”.hashCode()); //3254818
System.out.println(“python”.hashCode()); //-973197092
System.out.println(“scala”.hashCode()); //109250886
System.out.println(“---------”);
System.out.println(“无”.hashCode()); //26080
System.out.println(“敌”.hashCode()); //25932
}
}
7.3 数据结构之哈希表
-
JDK8之前,底层采用数组+链表实现,可以说是一个元索为链表的数组(哈希表 = 数组 + 链表 + (哈希算法))
-
JDK8以后,在长度比较长的时候,底层实现了优化(哈希表 = 数组 + 链表 + 红黑树 + (哈希算法))
-
当链表长度超过 8 时,将链表转换为红黑树,这样大大减少了查找时间
7.4 HashSet集合概述和特点
-
HashSet集合特点
-
底层数据结构是哈希表
-
对集合的迭代顺序不作任何保证 ,也就是说不保证存储和取出的元素顺序一致
-
没有带索引的方法,所以不能使用普通for循环遍历
-
由于是Set集合, 所以是不包含重复元素的集合
package ceshi;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
HashSet hs = new HashSet<>();
hs.add(“java”);
hs.add(“python”);
hs.add(“scala”);
hs.add(“scala”);
for(String s:hs) {
System.out.println(s);
/*python
java
scala*/
}
}
}
7.5 HashSet集合保证元素唯一性源码分析(重点面试常考)
HashSet hs = new HashSet<>();
hs.add(“java”);
hs.add(“python”);
hs.add(“scala”);
hs.add(“scala”);
for(String s:hs) {
System.out.println(s);
/*python
java
scala*/
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true); //上个方法的返回的值是hash(key)的值
}
//hash值和元素的hashCode()方法
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
//如果哈希表未初始化就对其初始化
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//根据对象的哈希值计算对象的存储位置,
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null); //如果该位置没有元素,就存储新元素
//有元素就走else
else {
Node<K,V> e; K k;
//存入的元素和以前的元素比哈希值
if (p.hash == hash &&
//二、如果哈希值相同,调用对象的equals()比较内容是否相同
//1、如果内容不同equals()返回false,就走一把元素添加到集合
//2、如果内容相同返回true,说明元素重复,走e = p;不存储
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
//一、如果哈希值不同,就走else存储元素到集合
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null); //新元素添加到集合
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
-
HashSet集合存储元素:要保证元素唯一性需要重写
hashCode()
和equals()
方法 -
案例
- Student类
package ceshi;
public class 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;
}
//重写快捷键:Fn+Alt+insert,选择equals() and hashCode()
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
- 测试类
package ceshi;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
HashSet hs = new HashSet<>();
Student s1 = new Student(“y1”,10);
Student s2 = new Student(“y2”,20);
Student s3 = new Student(“y3”,30);
Student s4 = new Student(“y3”,30);
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
for(Student s: hs) {
System.out.println(s.getName()+“,”+s.getAge());
/*y3,30
y2,20
y1,10
y3,30;s4内容和s3重复并存入了,需要重写hashCode()和equals()
*/
//重写后
/*
y1,10
y3,30
y2,20*/
}
}
}
7.6 LinkedHashSet集合概述和特点
-
LinkedHashSet集合特点
-
哈希表和链表实现的Set接口, 具有可预测的迭代次序
-
由链表保证元素有序, 也就是说元索的存储和取出顺序是一致的
-
由哈希表保证元索唯一, 也就是说没有重复的元素
package ceshi;
import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
public static void main(String[] args) {
LinkedHashSet linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add(“java”);
linkedHashSet.add(“python”);
linkedHashSet.add(“scala”);
linkedHashSet.add(“scala”);
for(String s:linkedHashSet) {
System.out.println(s);
/*java
python
scala*/
}
}
}
7.7 TreeSet集合概述和特点
-
TreeSet集合特点
-
元素有序, 这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法
TreeSet()
:根据其元素的自然排序进行排序
TreeSet(Comparator comparator)
:根据指定的比较器进行排序
-
没有带索引的方法,所以不能使用普通for循环遍历
-
由于是Set集合,所以不包含重复元素的集合
package ceshi;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet<>();
//jdk5以后添加元素自动装箱int》integer
ts.add(10);
ts.add(40);
ts.add(30);
ts.add(50);
ts.add(20);
ts.add(30);
for(Integer i:ts) {
System.out.println(i);
/*
10
20
30
40
50*/
}
}
}
7.8 自然排序Comarable的使用
-
存储学生对象并遍历,创建TreeSet集合使用无参构造方法
-
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
-
结论:
-
用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
-
自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
-
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
-
Student类
package ceshi;
public class Student implements Comparable{ //实现接口
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 int compareTo(Student s) {
// return 0; //返回0说明元素是重复的,只能存一个元素
// return 1; //整数是升序排序
// return -1; //负数是倒叙排序
//按照年龄排序
int num = this.age-s.age; //this是s2,s是s1
//年龄相同时,按照名字字母排序
int num2 = num==0 ? this.name.compareTo(s.name):num;
return num2;
}
}
- 测试
package ceshi;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet<>();
Student s1 = new Student(“y1”,10);
Student s2 = new Student(“y3”,30);
Student s3 = new Student(“y2”,20);
Student s4 = new Student(“y4”,40);
Student s5 = new Student(“a4”,40); //判断按字母排序
Student s6 = new Student(“y4”,40); //判断会存储重复值吗
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
for(Student s:ts) {
System.out.println(s.getName()+“,”+s.getAge());
/*y1,10
y2,20
y3,30
a4,40
y4,40*/
}
}
}
7.9 比较器排序Comparator[kəmˈpɜrətər]的使用
-
存储学生对象并遍历,创建TreeSet集合使用带参构造方法
-
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
-
结论
-
用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元索进行排序的
-
比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(To1,T o2)方法
-
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
package ceshi;
public class 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;
}
}
- 测试
package ceshi;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet<>(new Comparator() {
@Override
public int compare(Student s1, Student s2) {
int num = s1.getAge() - s2.getAge();
int num2 = num==0? s1.getName().compareTo(s2.getName()):num;
return num2;
}
});
Student s1 = new Student(“y2”,20);
Student s2 = new Student(“y1”,10);
Student s3 = new Student(“y3”,30);
Student s4 = new Student(“y4”,40);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
for(Student s:ts) {
System.out.println(s.getName()+“,”+s.getAge());
}
}
}
7.10 案例:不重复随机数
package ceshi;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
public class SetDemo {
public static void main(String[] args) {
// Set set = new HashSet<>();
Set set = new TreeSet<>();
Random r = new Random();
//判断集合是否《10
while(set.size()<10) {
int number = r.nextInt(20)+1;
set.add(number); //把随机数添加到集合
}
for (Integer i:set) {
System.out.print(i+" "); //1(哈希set集合):16 17 2 20 8 9 10 11 14 15
//2(TreeSet集合):1 3 4 5 6 7 8 10 16 19
}
}
}
-
HashMap
: 元素按照键是无序,不重复,无索引,值不做要求 -
LinkedHashMap
: 元素按照键是有序,不重复,无索引,值不做要求
8.1 Map集合概述和特点
-
Map集合是一种双列集合,每个元素包含两个值
-
Interface Map<K,V>; K:键的类型,V:值的类型
-
Map集合的每个元素的格式:key = value(键值对元素)
-
Map集合也被称为“键值对集合”
-
Map集合特点:
-
Map 集合的键是无序,不重复,无索引的
-
Map 集合后面重复的键对应的元素会覆盖前面的整个元素
-
创建Map集合对象:
-
多态的方式
-
具体的实现类HashMap
package ceshi;
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put(“y1”,“10”);
map.put(“y2”,“20”);
map.put(“y2”,“30”); //键和前面相同时,会替换前面的值
map.put(“y3”,“30”);
System.out.println(map); //{y1=10, y3=30, y2=30}
}
}
8.2 Map集合的基本方法
| 方法名 | 说明 |
| — | — |
| public V put(K key, V value) | 添加元素 |
| public V remove(Object key) | 根据键删除键值对元素 |
| public void clear() | 移除所有键值对元素 |
| public boolean containKey(Object key) [kənˈteɪn] | 判断集合是否包含指定的键 |
| public boolean containValue(Object value) | 判断集合是否包含指定的值 |
| public boolean isEmpty() | 判断集合是否为空 |
| public int size() | 集合的长度,也就是集合中键值对个数 |
package ceshi;
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
//1,public V put(K key, V value) 添加元素
map.put(“y1”,“10”);
map.put(“y2”,“20”);
map.put(“y3”,“30”);
System.out.println(map); //{y1=10, y2=20, y3=30}
//2,public V remove(Object key) 根据键删除键值对元素
/*map.remove(“y2”);
System.out.println(map); //{y1=10, y3=30}
*/
//3,public void clear() 移除所有键值对元素
/* map.clear();
System.out.println(map); //{}
*/
//4,public boolean containKey(Object key) [kənˈteɪn] 判断集合是否包含指定的键
/*System.out.println(map.containsKey(“y2”)); //ture
System.out.println(map.containsKey(“y4”)); //false*/
//5,public boolean containValue(Object value) 判断集合是否包含指定的值
// System.out.println(map.containsValue(“10”)); //true
//6,public boolean isEmpty() 判断集合是否为空
// System.out.println(map.isEmpty()); //false
//7,public int size() 集合的长度,也就是集合中键值对个数
System.out.println(map.size()); //3
}
}
8.3 Map集合的获取方法(重点)
| 方法名 | 说明 |
| — | — |
| public V get(Object key) | 根据键获取值 |
| public Set<K> keySet()
| 获取所有键的集合,存储到Set集合中 |
| public Collection<V> values()
| 获取所有值的集合,存储到Collection集合中 |
| public Set<Map.Entry<K,V>> entrySet()
| 获取所有键值对对象的集合(Set集合) |
package ceshi;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
//public V put(K key, V value) 添加元素
map.put(“y1”,“10”);
map.put(“y2”,“20”);
map.put(“y3”,“30”);
System.out.println(map); //{y1=10, y2=20, y3=30}
//1,public V get(Object key) 根据键获取值
System.out.println(map.get(“y1”)); //10
System.out.println(map.get(“y4”)); //null
//2,public Set keySet() 获取所有键的集合,存储到Set集合中
Set key = map.keySet();
for(String s:key) {
System.out.println(s);
/*y1
y2
y3*/
}
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
age ceshi;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
public class SetDemo {
public static void main(String[] args) {
// Set set = new HashSet<>();
Set set = new TreeSet<>();
Random r = new Random();
//判断集合是否《10
while(set.size()<10) {
int number = r.nextInt(20)+1;
set.add(number); //把随机数添加到集合
}
for (Integer i:set) {
System.out.print(i+" "); //1(哈希set集合):16 17 2 20 8 9 10 11 14 15
//2(TreeSet集合):1 3 4 5 6 7 8 10 16 19
}
}
}
-
HashMap
: 元素按照键是无序,不重复,无索引,值不做要求 -
LinkedHashMap
: 元素按照键是有序,不重复,无索引,值不做要求
8.1 Map集合概述和特点
-
Map集合是一种双列集合,每个元素包含两个值
-
Interface Map<K,V>; K:键的类型,V:值的类型
-
Map集合的每个元素的格式:key = value(键值对元素)
-
Map集合也被称为“键值对集合”
-
Map集合特点:
-
Map 集合的键是无序,不重复,无索引的
-
Map 集合后面重复的键对应的元素会覆盖前面的整个元素
-
创建Map集合对象:
-
多态的方式
-
具体的实现类HashMap
package ceshi;
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put(“y1”,“10”);
map.put(“y2”,“20”);
map.put(“y2”,“30”); //键和前面相同时,会替换前面的值
map.put(“y3”,“30”);
System.out.println(map); //{y1=10, y3=30, y2=30}
}
}
8.2 Map集合的基本方法
| 方法名 | 说明 |
| — | — |
| public V put(K key, V value) | 添加元素 |
| public V remove(Object key) | 根据键删除键值对元素 |
| public void clear() | 移除所有键值对元素 |
| public boolean containKey(Object key) [kənˈteɪn] | 判断集合是否包含指定的键 |
| public boolean containValue(Object value) | 判断集合是否包含指定的值 |
| public boolean isEmpty() | 判断集合是否为空 |
| public int size() | 集合的长度,也就是集合中键值对个数 |
package ceshi;
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
//1,public V put(K key, V value) 添加元素
map.put(“y1”,“10”);
map.put(“y2”,“20”);
map.put(“y3”,“30”);
System.out.println(map); //{y1=10, y2=20, y3=30}
//2,public V remove(Object key) 根据键删除键值对元素
/*map.remove(“y2”);
System.out.println(map); //{y1=10, y3=30}
*/
//3,public void clear() 移除所有键值对元素
/* map.clear();
System.out.println(map); //{}
*/
//4,public boolean containKey(Object key) [kənˈteɪn] 判断集合是否包含指定的键
/*System.out.println(map.containsKey(“y2”)); //ture
System.out.println(map.containsKey(“y4”)); //false*/
//5,public boolean containValue(Object value) 判断集合是否包含指定的值
// System.out.println(map.containsValue(“10”)); //true
//6,public boolean isEmpty() 判断集合是否为空
// System.out.println(map.isEmpty()); //false
//7,public int size() 集合的长度,也就是集合中键值对个数
System.out.println(map.size()); //3
}
}
8.3 Map集合的获取方法(重点)
| 方法名 | 说明 |
| — | — |
| public V get(Object key) | 根据键获取值 |
| public Set<K> keySet()
| 获取所有键的集合,存储到Set集合中 |
| public Collection<V> values()
| 获取所有值的集合,存储到Collection集合中 |
| public Set<Map.Entry<K,V>> entrySet()
| 获取所有键值对对象的集合(Set集合) |
package ceshi;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
//public V put(K key, V value) 添加元素
map.put(“y1”,“10”);
map.put(“y2”,“20”);
map.put(“y3”,“30”);
System.out.println(map); //{y1=10, y2=20, y3=30}
//1,public V get(Object key) 根据键获取值
System.out.println(map.get(“y1”)); //10
System.out.println(map.get(“y4”)); //null
//2,public Set keySet() 获取所有键的集合,存储到Set集合中
Set key = map.keySet();
for(String s:key) {
System.out.println(s);
/*y1
y2
y3*/
}
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-kXpxXoat-1715743871182)]
[外链图片转存中…(img-ai02TxUK-1715743871182)]
[外链图片转存中…(img-7mM3QYZZ-1715743871183)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!