45.Arrays
一. 排序: 排序就是将一组数据按照一定的规则进行排列;
类:
排序算法:https://blog.csdn.net/meini32/article/details/109070011
1.Arrays类的概述和常用方法
概述:Arrays类包含用于操作数组的各种方法
方法名 | 说明 |
---|---|
public static String toString(int[] a) | 返回指定数组的内容的字符串表示形式 |
public static void sort(int[] a) | 按照数字顺序排列指定的数组 |
import java.util.Arrays;
public class ArraysDemo {
public static void main(String[] args) {
int[] a={24,45,7,89,6,39};
System.out.println("排序前:"+ Arrays.toString(a));
Arrays.sort(a);
System.out.println("排序后:"+Arrays.toString(a));
// 排序前:[24, 45, 7, 89, 6, 39]
// 排序后:[6, 7, 24, 39, 45, 89]
}
}
工具类(Arrays Math 等)的设计思想:
- 构造方法用private修饰(防止外界创建对象)
- 成员用public static 修饰(使用类名来构造成员方法)
46.基本类型包装类
1.概述
将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据。
操作: 基本数据类型和字符串的转换
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
public class IntegerDemo {
//基本类型 包装类
public static void main(String[] args) {
//需求:判断一个数是否在int范围内?
//public static final int MIN_VALUE (最终类不可能有子类)
//public static final int MAX_VALUE
System.out.println(Integer.MAX_VALUE);//2147483647
System.out.println(Integer.MIN_VALUE);//-2147483648
}
}
2.Integer类的概述和使用
Integer:包装一个对象中的原始类型int的值
import sun.security.krb5.internal.crypto.EType;
import java.lang.reflect.Type;
public class IntegerDemo1 {
public static void main(String[] args) {
//根据int值创建String对象
Integer i1 = new Integer(100);
System.out.println(i1);
System.out.print("i1是否为int类型? ");
System.out.println(i1 instanceof Integer); //判断是否为int类型
//返回表示指定的int值的Integer实例
Integer i2 = Integer.valueOf(100);
System.out.println(i2);
System.out.print("i2是否为int类型? ");
System.out.println(i2 instanceof Integer); //判断是否为int类型
//根据String值创建int对象
Integer i3 = new Integer("100");
System.out.println(i3);
System.out.print("i3是否为int类型? ");
System.out.println(i3 instanceof Integer); //判断是否为int类型
//返回一个保存指定值的Integer对象String
Integer i4 = Integer.valueOf("100");
System.out.println(i4);
System.out.print("i4是否为int类型? ");
System.out.println(i4 instanceof Integer); //判断是否为int类型
}
}
3.int和String的相互转换
基本类行包装类最常见的操作:用于基本类型和字符串之间的相互转换;
- int–>String
public static String valueOf(int i):返回int参数的字符串表示形式,该方法是String类中的方法; - String–>int
public static int parseInt(String s):将字符串解析为int类型,该方法是Integer类中的方法
package Integerr;
//int和String的相互转换
public class IntegerDemo2 {
public static void main(String[] args) {
//int-->String
int num = 100;
String s1 = "" + num; //方法1
System.out.println(s1);
System.out.print("s1是否为String类型? ");
System.out.println(s1 instanceof String);
String s2 = String.valueOf(num); //方法2
System.out.println(s2);
System.out.print("s2是否为String类型? ");
System.out.println(s2 instanceof String);
//String-->int
String s = "123";
Integer i = Integer.valueOf(s); //方法1: String-->Integer-->int
int x = i.intValue();
System.out.print("x是否为int类型? ");
System.out.println(x + 0);
int y = Integer.parseInt(s); //方法2:直接转换
System.out.print("y是否为int类型? ");
System.out.println(y + 0);
}
}
4.案例:字符串中数据排序
需求:有一个字符串:“91 27 46 38 50”,请写程序实现最终输出结果:“27 38 46 50 91”
实现:https://blog.csdn.net/meini32/article/details/125645597
5.自动装箱和拆箱
- 装箱:把基本数据类型转换为对应的包装类型;
- 拆箱:把包装类型转换为基本数据类型;
package Integerr;
/*
* 自动装箱和拆箱
* */
public class IntegerDemo3 {
public static void main(String[] args) {
//装箱:把基本数据类型转换为对应的包装类型
Integer i = Integer.valueOf(100); //手动装箱(明确调用方法)
Integer i1 = 100; //自动装箱
//拆箱
int i2 = i1.intValue(); //手动拆箱
i1+=100;
System.out.println(i1); //自动拆箱(可以直接使用包装类型进行运算)
}
}
47.日期类
1.Date类概述及其构造方法
概述:Date代表一个特定的时间,精确到毫秒;
方法名 | 说明 |
---|---|
public Date() | 分配一个Date对象,并初始化,以便代表它被分配的时间,精确到毫秒 |
public Date(long date) | 分配一个Date对象,并初始化为表示从标准基准时间(1970.1.1)起指定的毫秒数 |
package Datee;
import java.util.Date;
public class DateDemo {
public static void main(String[] args) {
Date d1 = new Date();
System.out.println(d1); //Thu Jul 07 00:30:34 CST 2022
long l = 1000*60*60;
Date d2 = new Date(l);
System.out.println(d2); //Thu Jan 01 09:00:00 CST 1970
}
}
2.Date类的常用方法
方法名 | 说明 |
---|---|
public long getTime() | 获取的是日期对象从1970.1.1的00:00:00到现在的毫秒值 |
public void setTime(long time) | 设置时间,给的是毫秒值 |
package Datee;
import java.util.Date;
public class DataDemo1 {
public static void main(String[] args) {
Date d1 = new Date();
System.out.println(d1.getTime() + "ms");
System.out.println(d1.getTime() * 1.0 / 1000 / 60 / 60 / 24 / 365 + "years");
long t1 = 1000*60*60;
d1.setTime(t1);
System.out.println(d1);
long t2 = System.currentTimeMillis(); //获取当前时间;
d1.setTime(t2);
System.out.println(d1);
}
}
/*
52.54710795988711years
Thu Jan 01 09:00:00 CST 1970
Thu Jul 07 00:39:56 CST 2022
**/
3.SimpleDateFormat类概述
SimpleDateFormat类是一个具体类,用于以区域设置敏感的方式 格式化和解析日期。
日期和时间格式由日期和时间模式字符串指定。
在日期和时间模式字符串中,从‘A’到‘Z’以及从‘a’到‘z’引导的字母被解释为表示日期和时间字符串组件的模式字母。
- y–>年
- M–>月
- d–>日
- H–>时
- m–>分
- s–>秒
4.SimpleDateFormat的构造方法
方法名 | 说明 |
---|---|
public SimpleDateFormat() | 构造一个SimpleDateFormat,使用默认模式和日期格式 |
public SimpleDateFormat(String parttern) | 构造一个SimpleDateFormat使用指定模式和默认日期格式 |
5.SimpleDateFormat格式化和解析日期
- 格式化(Date–>String)
public final String format(Date date):将日期格式化成日期/时间字符串; - 解析(String–>Date)
public Date parse(String source):从给定字符串开始解析文本生成日期;
package Datee;
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();
SimpleDateFormat sdf = new SimpleDateFormat(); //默认日期模式
String f = sdf.format(d);
System.out.println(f); //22-7-8 上午12:11
SimpleDateFormat sdf1 = new SimpleDateFormat("yy年MM月dd日 HH:mm:ss"); //自定义模式
String f1 = sdf1.format(d);
System.out.println(f1); //22年07月08日 00:15:02
//解析:String-->Date
String s = "22-7-9 12:15:36";
SimpleDateFormat sdf2 = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); //模式需要和字符串上的时间格式一样
Date d2 = sdf2.parse(s);
System.out.println(d2); //Sat Jul 09 12:15:36 CST 2022
}
}
6.案例:日期工具类
需求:定义一个日期工具类(DateUtils),包含两个方法:
- 把日期转换成指定格式的字符串(dateToString)
- 把字符串解析成指定格式日期(StringToDate)
定义一个测试类:测试工具类的方法
package Datee;
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 f = sdf.format(date);
return f;
}
//把字符串解析成指定格式日期
public static Date StringToDate(String s,String format) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date d = sdf.parse(s);
return d;
}
}
package Datee;
import java.text.ParseException;
import java.util.Date;
/*
* 测试类
* */
public class DateUtilsDemo {
public static void main(String[] args) throws ParseException {
Date d = new Date();
String s = DateUtils.dateToString(d,"yy年MM月dd日 HH:mm:ss");
System.out.println(s);
String s1 ="2022.12.15 05:15:23";
Date d1 = DateUtils.StringToDate(s1,"yy.MM.dd HH:mm:ss");
System.out.println(d1);
}
}
7.Calendar类
概述 :Calendar类为某一时刻和一组日历字段之间的转换提供了方法,并为操作日历字段提供了一些方法;
方法名 | 说明 |
---|---|
getInstance() | 获取Calendar对象 |
package Datee;
import java.util.Calendar;
public class CalendarDemo {
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
System.out.println(c);
/*java.util.GregorianCalendar[time=1657213270044,areFieldsSet=true,areAllF
ieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shan
hai",offset=28800000,dstSavings=0,useDaylight=false,transitions=29,lastRule=null],
irstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2022,MONTH=6,WEEK_OF_YEAR=28,
WEEK_OF_MONTH=2,DAY_OF_MONTH=8,DAY_OF_YEAR=189,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=2,A
M_PM=0,HOUR=1,HOUR_OF_DAY=1,MINUTE=1,SECOND=10,MILLISECOND=44,ZONE_OFFSET=28800000,DST_OFFSET=0]*/
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;
int day = c.get(Calendar.DATE);
System.out.println(year+"年"+month+"月"+day+"日"); //2022年7月8日
}
}
8.Calendar的常用方法
方法名 | 说明 |
---|---|
public static get(int field) | 返回给定日历字段 |
public abstract void add(int field,int amount) | 根据日历规则,将指定时间量添加或减去给定日历字段 |
public final void set(int year,int month,int date) | 设置当前日历的年月日 |
package Datee;
import java.util.Calendar;
public class CalendarDemo {
public static void main(String[] args) {
Calendar c = Calendar.getInstance(); //获取日历对象
int year = c.get(Calendar.YEAR); //返回给定日历字段的值
int month = c.get(Calendar.MONTH)+1;
int day = c.get(Calendar.DATE);
System.out.println(year+"年"+month+"月"+day+"日"); //2022年7月8日
c.add(Calendar.YEAR,-3); //将指定时间量添加或减去给定日历字段
System.out.println(c.get(Calendar.YEAR)+"年"+c.get(Calendar.MONTH)+"月"+c.get(Calendar.DATE)+"日"); //三年前的今天
c.set(2025,12,15);
System.out.println(c.get(Calendar.YEAR)+"年"+c.get(Calendar.MONTH)+"月"+c.get(Calendar.DATE)+"日");
}
}
9.案例:二月天
需求:获取任意一年有多少天
package Datee;
import java.util.Calendar;
import java.util.Scanner;
/*
* 二月天
* */
public class FebruaryDays {
public static void main(String[] args) {
System.out.print("请输入年分:");
Scanner sc = new Scanner(System.in);
int year = sc.nextInt();
Calendar c = Calendar.getInstance();
c.set(year,2,1); //三月一日
c.add(Calendar.DATE,-1); //三月一日前一天
int days = c.get(Calendar.DATE);
System.out.println(year+"年的二月有:"+ days);
}
}
48.异常
1.概述: 程序出现了不正常的情况;
2.JVM的默认处理方式
JVM: JVM是JavaVirtualMachine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
JVM与java程序的关系:https://baijiahao.baidu.com/s?id=1710167554881092125&wfr=spider&for=pc
JVM对异常的默认处理方式:
如果程序出现了问题,我们没有做任何处理,最终JVM会做默认处理:
- 把异常的名称、异常原因、异常出现的位置信息输出在控制台上;
- 程序停止运行;
package Exceptions;
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("start");
method();
System.out.println("end");
}
private static void method() {
int[] l = {1,2,3,4};
System.out.println(l[6]);
}
}
3.异常处理
如果程序出现了问题,需要我们自己解决:
- try…catch…
- throws
3.1 try…catch…
- 格式
try{
可能出现的异常代码;
}catch(异常类名 变量名){
异常处理代码;
}
- 执行流程
程序从try开始执行;
出现异常时会自动生成一个异常类,该异常对象被提交给Java运行时系统;
当系统接收到异常对象,会到catch中找匹配的异常类,找到后进行异常处理;
执行完毕后,系统可以继续往下执行;
package Exceptions;
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("start");
method();
System.out.println("end");
}
private static void method() {
try {
int[] l = {1, 2, 3, 4};
System.out.println(l[6]);
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("数组索引过界");
}
}
}
/*
start
数组索引过界
end
*/
也可以采用直接输出系统错误:
3.2 Throwable
- 成员方法
方法名 | 说明 |
---|---|
public String getMessage() | 返回此Throwable的详细信息 |
public String toString() | 返回可抛出的简短描述 |
public void printStackTrance() | 把异常信息输出到控制台 |
package Exceptions;
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("start");
method();
System.out.println("end");
}
private static void method() {
try {
int[] l = {1, 2, 3, 4};
System.out.println(l[6]); //产生一个异常对象 new ArrayIndexOutOfBoundsException();
}catch (ArrayIndexOutOfBoundsException e){
System.out.println(e.getMessage()); //6
System.out.println(e.toString());//java.lang.ArrayIndexOutOfBoundsException: 6
e.printStackTrace(); /*java.lang.ArrayIndexOutOfBoundsException: 6
at Exceptions.ExceptionDemo.method(ExceptionDemo.java:13)
at Exceptions.ExceptionDemo.main(ExceptionDemo.java:6)*/
}
}
}
3.3编译时异常和运行时异常的区别
- 编译时异常(非 RuntimeException):必须显示处理,否则程序出错无法通过编译;
- 运行时异常( RuntimeException):无需显示处理;
//其实就是你写代码的时候,如果写着写着底线有个红色波浪线 那就是编译时异常
3.4 throws处理异常
使用情景:不是所有异常都可以使用try…catch…,有些异常我们没有权限去进行处理,这时可以采用throws处理方案;
- 格式
throw 异常类名;
- 针对运行时异常:throws仅仅是输出错误信息,并不能给出解决方案,程序无法执行完毕;
package Exceptions;
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("start");
method();
System.out.println("end");
}
private static void method() throws ArrayIndexOutOfBoundsException{ //throws
int[] l = {1, 2, 3, 4};
System.out.println(l[6]); //产生一个异常对象
}
}
/*
start
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at Exceptions.ExceptionDemo.method(ExceptionDemo.java:13)
at Exceptions.ExceptionDemo.main(ExceptionDemo.java:6)*/
- 针对编译时异常:并没有进行实质的处理只是抛给了main函数的调用者,即:谁使用谁负责,最终还是要使用try…catch处理
package Exceptions;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("start");
method();
try {
method1();
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("end");
}
private static void method1() throws ParseException {
String s = "2022-1-1";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
Date d= simpleDateFormat.parse(s);
System.out.println(d);
}
private static void method(){
int[] l = {1, 2, 3, 4};
System.out.println(l[1]);
}
}
3.5 自定义异常
- 格式
public class 异常类名 extends Exception{
无参构造;
带参构造;
}
- 案例:分数异常
package Exceptions;
//自定义有个分数异常类
public class ScoreException extends Exception{
public ScoreException() {}
public ScoreException(String message) {
super(message);
}
}
package Exceptions;
//定义有个老师类来使用分数异常
public class Teacher {
public void checkScore(int score) throws ScoreException {
if(score <0||score>100){
throw new ScoreException("您输入的分数不正确"); //throw 用于在方法体内部抛出异常; 因为是我们自定义的所以我们手动去抛;
}else {
System.out.println("分数正常");
}
}
}
package Exceptions;
//测试类
import java.util.Scanner;
public class ScoreDemo {
public static void main(String[] args) {
System.out.print("请输入您的分数:");
Scanner sc = new Scanner(System.in);
int score = sc.nextInt();
Teacher t = new Teacher();
//编译时异常
try {
t.checkScore(score);
} catch (ScoreException e) {
e.printStackTrace();
}
}
}
3.6 throw和throws的区别
throws | throw |
---|---|
用在方法声明后边,跟的是异常类名 | 用在方法体内,跟的是异常对象名 |
表示抛出异常,由该方法的调用者来处理 | 表示抛出异常,由方法体内语句进行处理 |
表示出现异常的一种可能性,并不一定会发生异常 | 执行throw一定抛出了某种异常 |
49.集合系统结构
1.Collection集合
1.1 Collection集合的概述
- 是单列集合的顶层接口,表示一组对象,这些对象也称为Collection的元素;
- JDK不提供Collection接口的任何直接实现,它提供更具体的子接口(List和Set)来实现
1.2 创建Collection集合对象
- 多态的方法
- 具体的实现类ArrayList;
package Collections;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
//创建Collection对象
Collection<String> c =new ArrayList<String>();
//添加元素
c.add("hello");
c.add("nihao");
//输出
System.out.println(c); //[hello, nihao]
}
}
1.3 Collection集合的常用方法
方法名 | 说明 |
---|---|
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定元素 |
void clear() | 清除集合中所以元素 |
boolean contains(Object o) | 判断集合中是否存在指定元素 |
boolean isEmpty() | 判断是否集合为空 |
int size | 集合的长度(元素个数) |
1.4 Collection 集合遍历
Iteration :迭代器,集合的专用遍历方式;
- Iteration iteration():返回此集合元素的迭代器,通过集合的iterator得到;
- 依赖集合而存在
方法名 | 说明 |
---|---|
E next() | 返回迭代中的下一个元素 |
boolean hasNext() | 如果迭代具有的更多元素,则返回true |
package Collections;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class IteratorDemo {
public static void main(String[] args) {
Collection<String> c = new ArrayList<String>();
c.add("aa");
c.add("bb");
c.add("cc");
Iterator<String> it = c.iterator();
System.out.println(it.next()); //aa
System.out.println(it.next()); //bb
System.out.println(it.next()); //cc
// System.out.println(it.next()); //NoSuchElementException
while (it.hasNext()){ //不用一条一条的遍历
System.out.println(it.next());
};
}
}
1.5 集合的使用步骤
1.6 案例 Collection集合存储学生对象并遍历
需求: 创建有个学生对象,存储三个学生对象,使用程序实现在控制台遍历该集合;
思路:
- 创建学生类
- 创建Collection集合对象
- 创建学生对象
- 把学生添加到集合
- 遍历集合
package Collections;
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 Collections;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionStudent {
public static void main(String[] args) {
//创建Collection对象
Collection<Student> c = new ArrayList<Student>();
//创建学生对象
Student s1 = new Student("nini",18);
Student s2 = new Student("tudou",1);
Student s3 = new Student("longjie",24);
//添加学生对象到集合
c.add(s1);
c.add(s2);
c.add(s3);
//遍历集合(通过迭代器)
Iterator<Student> it = c.iterator();
while (it.hasNext()){
Student s = it.next();
System.out.println(s.getName()+" "+s.getAge());
}
}
}
2.List集合
2.1 List集合概述和特点
- 有序集合(也称有序列),用户可以精准的控制列表中每一个元素的插入位置,也可以通过索引来访问元素搜索列表中的元素;
- 与set不同,List集合允许元素重复
package Lists;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<String>();
//添加元素
list.add("aa");
list.add("bb");
//输出集合对象
System.out.println(list); //[aa, bb]
//遍历(迭代器)
Iterator<String> it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
2.2 List集合的特有方法
List继承Collection集合的方法
方法名 | 特点 |
---|---|
void add(int index,E element) | 在指定位置插入元素,被插入的元素往后移 |
E remove(int index) | 删除指定索引处的元素,返回被删除元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改元素 |
E get(int index) | 返回索引元素 |
2.3 List集合的并发修改异常
当集合不允许这样的修改时,可以通过检测到对象的并发修改的方法来抛出异常;
- 产生原因
迭代器在遍历时候,通过集合对象修改集合中元素的长度,造成迭代器获取元素中判断预期修改值和实际修改值不一样
- 解决方案
用佛如循环进行遍历,然后用集合对象做对应的操作
package Lists;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<String>();
//添加元素
list.add("aa");
list.add("bb");
list.add("cc");
//输出集合对象
System.out.println(list); //[aa, bb]
//遍历(迭代器)
Iterator<String> it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
if(it.next().equals("bb")){
list.add("dd"); //ConcurrentModificationException 并发修改异常
}
}
}
}
采用size方法进行遍历就可以解决并发异常
package Lists;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<String>();
//添加元素
list.add("aa");
list.add("bb");
list.add("cc");
//输出集合对象
System.out.println(list); //[aa, bb]
//遍历
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
2.4 ListIterator
ListIterator:列表迭代器
- 通过List集合的listIterator()方法得到,是List集合特有的迭代器
- 用于允许程序员言任意方向遍历列表的列表迭代器,在迭代期间修改列表,并获取当前位置
方法名 | 说明 |
---|---|
E next() | 返回迭代的下一个元素 |
boolean hasNext() | 迭代更多元素 |
E previous() | 返回列表上一个元素 |
boolean hasPrevious() | 反方向遍历列表 |
void add(E e) | 将指定的元素插入列表 |
package Lists;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorDemo {
public static void main(String[] args) {
//创建集合对象
List<String> l = new ArrayList<>();
//添加元素
l.add("aa");
l.add("bb");
l.add("cc");
//正向迭代
ListIterator<String> lit = l.listIterator();
while (lit.hasNext()){
System.out.println(lit.next());
}
System.out.println("-----------");
//逆向迭代
while (lit.hasPrevious()){
System.out.println(lit.previous());
}
//获取列表迭代器
while (lit.hasNext()){
String s = lit.next();
if(s.equals("bb")){
lit.add("ee");
}
}
System.out.println(l);
}
}
2.5 增强for循环
增强for:简化数组和Collection集合的遍历
- 实现Iterable接口的类允许其对象成为增强型for语句目标
- 内部原理是一个Iterator迭代器
格式:
for(元素数据类型 变量名:数组或Collection集合){
//此处使用变量,该变量就是元素;
}
范例:
int[] arr = {1,2,3};
for (int i:arr){
sout(i)
}
2.6 数据结构
数据结构: 计算机存储、组织数据的方式。指相互之间存在一种或多种特定关系的元素集合;
列表常用的数据结构有:栈和队列,数组和链表;
数组的特点:
- 查询通过索引,效率高;
- 删除时要将原始数据删除,同时后边每个元素都有前移动,效率低;
- 添加时,添加位置后每个元素后移,添加效率低;
链表的特点:
- 查询数据需从头开始;
2.7 List集合子类的特点
List集合常用子类:ArrayList、LinkList
- ArrayList:底层数据结构是数组,查询快,增删慢;
- LinkList:底层数据结构是链表,查询慢,增删快;
练习:分别使用ArrayList、LinkList完成存储字符串和遍历;
package Lists;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorDemo {
public static void main(String[] args) {
//创建array对象
List<String> l = new ArrayList<>();
//添加元素
l.add("aa");
l.add("bb");
l.add("cc");
//遍历
for (String s:l){
System.out.println(s);
}
//创建link对象
List<String> ll = new LinkedList<String>();
ll.add("nini");
ll.add("sisi");
ll.add("soso");
for (String s:ll){
System.out.println(s);
}
}
}
2.8 LinkedList集合的特有功能
方法名 | 说明 |
---|---|
public void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
3.set集合
3.1 set集合概述和特点
- 不包含重复元素
- 没有带索引的方法,不能使用for循环
package Sets;
import java.util.HashSet;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
Set<String> s = new HashSet<String>();
//HashSet不保证迭代顺序
s.add("nihao");
s.add("hao");
s.add("no");
s.add("no");
for(String l:s){
System.out.println(l);
}
}
}
3.2 哈希值
哈希值: 是JDK根据对象的地址或者字符串或者数字算出来的int类型值;
获取Hash值: Object类中有一个方法可以获取对象的哈希值;
public int hashCode(); 返回的是对象的哈希值码;
同一个对象多次调用hashCode() 返回的hash值相同
默认情况下,不同对象调用hashCode() 返回的hash值不同
通过方法重写,不同对象调用hashCode() 返回的hash值相同
Case1 对象的哈希值:
package Hashs;
public class HashDemo {
public static void main(String[] args) {
Student s1 = new Student("nini",18);
Student s2 = new Student("coco",48);
System.out.println(s1.hashCode()); //460141958
System.out.println(s2.hashCode()); //1163157884
System.out.println(s1.hashCode()); //460141958
}
}
重写hashCode后:
Case2 字符串的哈希值:
package Hashs;
public class HashDemo {
public static void main(String[] args) {
System.out.println("nin".hashCode()); //109075
System.out.println("coco".hashCode()); //3059160
System.out.println("nin".hashCode()); //109075
}
}
3.3 HashSet集合概述和特点
HashSet集合特点
- 底层数据结构是哈希表
- 对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致;
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以是不包含重复元素的集合
HashSet集合练习:存储字符串并遍历
public static void main(String[] args) {
HashSet<String> s = new HashSet<String>();
//HashSet不保证迭代顺序
s.add("nihao");
s.add("hao");
s.add("no");
s.add("no");
for(String l:s){
System.out.println(l);
}
}
HashSet集合添加一个元素的过程:
HashSet集合存储元素:
要保证元素的唯一性,要重写hashCode()和equals()
3.4 常见数据结构之哈希表
哈希表
- JDK8之前,底层采用数组+链表实现,可以说是一个元素为链表的数组
- JDK8以后,在长度比较长的时候,底层实现了优化
3.5 案例 :HashSet集合存储学生对象并遍历
需求: 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
要求: 学生对象的成员变量值相同,我们就认为是同一个对象
思路:
- 定义学生类
- 创建HashSet集合
- 创建学生对象
- 把学生添加到集合
- 遍历集合(增强for)
package Hashs;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
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;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
package Hashs;
import java.util.HashSet;
public class HashDemo {
public static void main(String[] args) {
HashSet<Student> hs = new HashSet<Student>();
Student s1 = new Student("nini",18);
Student s2 = new Student("coco",48);
Student s3 = new Student("vivi",35);
Student s4 = new Student("vivi",35);
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4); //为了保证唯一性需要重写 HashCode
for (Student s:hs){
System.out.println(s.getName()+" "+s.getAge());
}
}
}
// nini 18
// coco 48
// vivi 35
3.6 LinkHashSet集合概述和特点
- 哈希表和链表实现的Set接口,具有可预测的迭代次序
- 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
- 由哈希表保证元素唯一,也就是说没有重复的元素
package Sets;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
LinkedHashSet<String> s = new LinkedHashSet<String>();
//HashSet不保证迭代顺序
s.add("nihao");
s.add("hao");
s.add("no");
s.add("no");
for(String l:s){
System.out.println(l);
}
}
}
// nihao
//hao
//no
3.7 TreeSet集合概述和特点
- 元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规测进行排序,具体排序方式取决于构造方法
- TreeSet():根据其元素的自然排序进行排序
- TreeSet(Comparator comparator):根据指定的比较器进行排序没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以不包含重复元素的集合
package Hashs;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<Integer>(); //这里整数型采用它的包装类
ts.add(80);
ts.add(30);
ts.add(20);
ts.add(62);
ts.add(30);
ts.add(10);
for(Integer i:ts){
System.out.println(i);
}
}
}
// 10
// 20
// 30
// 62
// 80
3.8 自然排序 Comparable 的使用
- 存储学生对象并遍历,创建TreeSet集合使用无参构造方法
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
心
结论
- 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序
- 对元素进行排序的自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(To)方法重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
package Hashs;
import java.util.Objects;
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
}
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;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student s) {
//return 0; 重复元素不添加
//return 1; //按照正序来存储;
//return -1; //按照降序来存储
int num = this.age-s.age;
return num;
}
}
package Hashs;
import java.util.TreeSet;
public class TreeSetDemo1 {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>();
Student s1 = new Student("nini",18);
Student s2 = new Student("coco",48);
Student s3 = new Student("vivi",35);
Student s4 = new Student("bii",35);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
for (Student s:ts){
System.out.println(s.getName()+" "+s.getAge());
}
}
}
3.9 比较器排序 Comparator的使用
- 存储学生对象并遍历,创建TreeSet集合使用带参构造方法
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
心
结论
- 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
- 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(To1,To2)方法
- 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
package Hashs;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
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;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
package Hashs;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo1 {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
//比较器规则
public int compare(Student o1, Student o2) {
//this.age-s.age
int num = o1.getAge()-o2.getAge();
int num2 = num==0?o1.getName().compareTo(o2.getName()):num;
return num2;
}
});
Student s1 = new Student("nini",18);
Student s2 = new Student("coco",48);
Student s3 = new Student("vivi",35);
Student s4 = new Student("bii",35);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
for (Student s:ts){
System.out.println(s.getName()+" "+s.getAge());
}
}
}
3.10 案例 成绩排序
需求: 用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合
要求: 按照总分从高到低出现
思路:
- 定义学生类
- 创建TreeSet集合对象,通过比较器排序进行排序
- 创建学生对象
- 把学生对象添加到集合
- 遍历集合
3.11 案例:不重复的随机数
- 需求:
编写一个程序,获取10个1-20之间的随机数,要求随机数不能重复,并在控制台输出
- 思路:
- 创建Set集合对象
- 创建随机数对象
- 判断集合的长度是不是小于10
是: 产生一个随机数,添加到集合回到3继续 - 遍历集合
java创建随机数的两种方法:https://blog.csdn.net/m0_54861649/article/details/124911883
package Sets;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class NoRepeatNum {
public static void main(String[] args) {
Set<Integer> st = new HashSet<Integer>();
Random r = new Random();
while(st.size()<10){
st.add(r.nextInt(20)+1);
}
System.out.println(st);
}
}
50.泛型
1.概述
泛型: 是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型;
// 它的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数;
参数化类的理解: 是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型,这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口
2.泛型定义格式:
- <类型>:指定一种类型的格式。这里的类型可以看成是形参
- <类型1,类型2.…>∶指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参
- 将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型
3. 泛型的好处:
把运行时期的问题提前到了编译期间避免了强制类型转换
package Generics;
import java.util.ArrayList;
import java.util.Collection;
public class GenericDemo {
public static void main(String[] args) {
//创建集合对象 (这里不给出具体数据类型,程序默认类型就是Object类型)
Collection c = new ArrayList();
//添加数据
c.add("mimi");
c.add(2);
c.add(2.3);
//遍历
for(Object obj:c){
System.out.println(obj);
}
}
}
不同数据类型采用迭代器进行遍历时:
package Generics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class GenericDemo {
public static void main(String[] args) {
//创建集合对象 (这里不给出具体数据类型,程序默认类型就是Object类型)
Collection<String> c = new ArrayList<String>();
//添加数据
c.add("mimi");
c.add("ni");
// c.add(10);
//遍历
Iterator<String> it = c.iterator();
while (it.hasNext()){ //向下转型为String类型
// Object obj = it.next();
// System.out.println(obj);
String s = it.next();
System.out.println(s); //ClassCastException Integer 不能转换成String
}
}
}
4.泛型类
泛型类的定义格式:
修饰符class类名<类型>{ }
//范例
public class Generic<T>{ }
注:此处T可以随便写为任意标识,常见的如T、E、K、v等形式的参数常用于表示泛型
应用情景:
package Generics;
// 学生类只定义姓名
public class Student {
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package Generics;
public class Teacher {
private Integer age;
public Teacher(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
package Generics;
//测试 类
public class GenericDemo1 {
public static void main(String[] args) {
//这里的老师类和学生类都分别只能接受一个单一的类型
// 所以我们在使用的时候传入的数据类型要与之规定的数据类型相对应
Teacher t = new Teacher(10);
System.out.println(t.getAge());
Student s= new Student("coco");
System.out.println(s.getName());
}
}
我们采用泛型类 ,就可以不用重新定义数据类型;
package Generics;
public class Generic <T>{
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
package Generics;
//测试 类
public class GenericDemo1 {
public static void main(String[] args) {
//定义 字符串类型
Generic<String> s = new Generic<String>();
s.setT("nini");
System.out.println(s.getT());
//定义int类型
Generic<Integer> s1 = new Generic<Integer>();
s1.setT(10);
System.out.println(s1.getT());
}
}
5.泛型方法
应用场景: 方法重载的使用
package Generics;
//方法的重写
public class Generic <T>{
public void show(String s){
System.out.println(s);
}
public void show(Integer i){
System.out.println(i);
}
public void show(boolean b){
System.out.println(b);
}
}
package Generics;
//测试 类
public class GenericDemo1 {
public static void main(String[] args) {
Generic g1 = new Generic();
g1.show(12);
g1.show("ni");
g1.show(true);
}
}
泛型类的改进
package Generics;
//方法的重写
public class Generic <T>{
public void show(T t){
System.out.println(t);
}
}
泛型方法的改进
package Generics;
//方法的重写
public class Generic{
public<T> void show(T t){
System.out.println(t);
}
}
6 类型通配符
概述: 为了表示各种泛型List的父类,可以使用类型通配符
- 类型通配符:<?>
List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中;
- 类型通配符上限:<? extends类型>
List<? extends Number> :它表示的类型是Number或者其子类型
- 类型通配符下限:<?super类型>
List<? super Number>:它表示的类型是Number或者其父类型
package Generics;
import java.util.ArrayList;
import java.util.List;
public class GenericDemo2 {
public static void main(String[] args) {
//类型通配符:<?>
List<?> list1 = new ArrayList<Object>();
List<?> list2 = new ArrayList<Number>();
List<?> list3 = new ArrayList<Integer>();
System.out.println("--------");
//类型通配符上限: <? extends类型>
// List<? extends Number> list4 = new ArrayList<Object>();
List<? extends Number> list5 = new ArrayList<Number>();
List<? extends Number> list6 = new ArrayList<Integer>();
System.out.println("--------");
//类型通配符下限:<?super类型 >
List < ? super Number > list7 = new ArrayList<Object>();
List<? super Number> list8 = new ArrayList<Number>();
// list<? super Number> list9 = new ArrayList<Integer>();
}
}
7.可变参数
概述: 可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
格式:修饰符返回值类型方法名(数据类型...变量名){}
范例: public static int sum(int...a){ }
应用场景:
package Generics;
public class GenericDemo3 {
public static void main(String[] args) {
System.out.println(sum(1,2,3,3,5));
}
public static int sum(int... a){
//相当于数组求和
int count=0;
for (int i:a){
count+=i;
}
return count;
}
}
8.可变参数的使用
package Generics;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GenericDemo4 {
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 1, 3, 6, 8, 9);
System.out.println(integers);
integers.set(1,99);
System.out.println(integers);
// [1, 1, 3, 6, 8, 9]
// [1, 99, 3, 6, 8, 9]
}
}
51.Map
1 Map集合概述和使用
Map集合概述
lnterface Map<K,V> //K:键的类型;V:值的类型
将键映射到值的对象;不能包含重复的键;每个键可以映射到最多一个值
举例:学生的学号和姓名
itheima001 林青霞
itheima002 张曼玉
itheima003 王祖贤
创建Map集合的对象
- 多态的方式
- 具体的实现类HashMap
package Maps;
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> m = new HashMap<String,String>();
m.put("001","meini");
m.put("002","td");
m.put("003","lj");
System.out.println(m);
// {001=meini, 002=td, 003=lj}
}
}
2. Map 的基本使用方法
方法名 | 说明 |
---|---|
put(K key,V value) | 添加元素 |
remove(Object key) | 根据键删除键值对元素 |
void clear | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
3 Map集合的获取功能
方法名 | 说明 |
---|---|
get(Object key) | 根据键获取值 |
Set key Set() | 获取所有键的集合 |
Collection values() | 获取所有值的集合 |
Set<Map.Entry > entrySet() | 获取所有键值对对象的集合 |
package Maps;
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> m = new HashMap<String,String>();
m.put("001","meini");
m.put("002","td");
m.put("003","lj");
//根据键获取值
System.out.println(m.get("002")); //td
//获取所有建集合
System.out.println(m.keySet()); //[001, 002, 003]
//或区所以值
System.out.println(m.values()); //[meini, td, lj]
//获取键值对
System.out.println(m.entrySet()); //[001=meini, 002=td, 003=lj]
}
}
4.Map集合的遍历
方式1: 把Map中的存储元素看成数据对的集合;
遍历思路:
- 把所有建集合起来; keySet()
- 遍历建的集合获取到每一个建; for
- 根据建找对应的值;get(key)
package Maps;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> m = new HashMap<String,String>();
m.put("001","meini");
m.put("002","td");
m.put("003","lj");
Set<String> keySet = m.keySet();
//遍历建
for(String s:keySet){
System.out.println(s);
System.out.println(m.get(s)); //根据建找值
}
}
}
方式二:
- 获取键值对集合; entrySet()
- 遍历每个键值对
- 根据键值对获取键值
getKey()
getValue()
package Maps;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> m = new HashMap<String,String>();
m.put("001","meini");
m.put("002","td");
m.put("003","lj");
Set<Map.Entry<String, String>> entries = m.entrySet();
//遍历
for(Map.Entry<String,String> me :entries){
System.out.println(me);
System.out.println(me.getKey()); //
System.out.println(me.getValue());
}
}
}
5 案例: HashMap集合存储学生对象并遍历
- 需求:
创建一个HashMap集合,键是学生对象(Student),值是居住地(String)。存储多个键值对元素,并遍历。
//要求保证键的唯一性:如果学生对象的成员变量值相同,我们就认为是同一个对象
思路:
- 定义学生类
- 创建HashMap集合对象
- 创建学生对象
- 把学生添加到集合
- 遍历集合
- 在学生类中重写两个方法
hashCode)
equals)
package Maps;
import java.util.Objects;
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "姓名:"+name+" "+"年龄"+age ;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
}
package Maps;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo1 {
public static void main(String[] args) {
Map<Student,String> sd = new HashMap<Student, String>();
Student s1 = new Student(18,"nini");
Student s2 = new Student(23,"lj");
Student s3 = new Student(22,"mini");
sd.put(s1,"北京");
sd.put(s2,"山东");
sd.put(s3,"南京");
Set<Map.Entry<Student, String>> entries = sd.entrySet();
for(Map.Entry<Student,String> me:entries){
System.out.println(me.getKey()+"="+me.getValue());
}
}
}
6 案例: ArrayList集合存储HashMap元素并遍历
需求:
创建一个ArrayList集合,存储三个元素,每一个元素都是HashMap,每一个HashMap的键和值都是String,并遍历
思路:
- 创建ArrayList集合
- 创建HashMap集合,并添加键值对元素
- 把HashMap作为元素添加到ArrayList集合
- 遍历ArrayList集合
package Maps;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo2 {
public static void main(String[] args) {
ArrayList<HashMap<String,String>> array = new ArrayList<HashMap<String,String>>();
HashMap<String,String> hm1 = new HashMap<String, String>();
hm1.put("001","nin");
hm1.put("002","coco");
hm1.put("003","vivi");
HashMap<String,String> hm2 = new HashMap<String, String>();
hm2.put("a","apple");
hm2.put("b","banana");
hm2.put("c","cup");
HashMap<String,String> hm3 = new HashMap<String, String>();
hm3.put("1","刘翔");
hm3.put("2","雄安镜头");
hm3.put("3","也是和大");
array.add(hm1);
array.add(hm2);
array.add(hm3);
for(HashMap<String,String> hm:array){
Set<Map.Entry<String, String>> entries = hm.entrySet();
for (Map.Entry<String, String> me:entries){
System.out.println(me.getKey()+" "+me.getValue());
}
}
}
}
// 001 nin
// 002 coco
// 003 vivi
// a apple
// b banana
// c cup
// 1 刘翔
// 2 雄安镜头
// 3 也是和大
7 案例:HashMap集合存储ArrayList元素并遍历
需求:
创建一个HashMap集合,存储三个键值对元素,每一个键值对元素的键是String,值是ArrayList,每一个ArrayList的元素是String,并遍历
思路:
- 创建HashMap集合
- 创建ArrayList集合,并添加元素
- 把ArrayList作为元素添加到HashMap集合
- 遍历HashMap集合
package Maps;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo3 {
public static void main(String[] args) {
Map<String,ArrayList<String>> m =new HashMap<String,ArrayList<String>>();
ArrayList<String> a1 = new ArrayList<String>();
a1.add("1");
a1.add("2");
a1.add("3");
ArrayList<String> a2 = new ArrayList<String>();
a1.add("a");
a1.add("b");
a1.add("c");
ArrayList<String> a3 = new ArrayList<String>();
a1.add("nini");
a1.add("coco");
a1.add("cici");
m.put("001",a1);
m.put("002",a2);
m.put("003",a3);
Set<Map.Entry<String, ArrayList<String>>> entries = m.entrySet();
for (Map.Entry<String, ArrayList<String>> me:entries){
ArrayList <String> a = me.getValue();
for(String s:a){
System.out.println(me.getKey()+" "+s);
}
}
}
}
8.案例 :统计字符串出现的次数
-
需求:
键盘录入一个字符串,要求统计字符串中每个字符串出现的次数。 -
举例:
键盘录入“aababcabcdabcde"
在控制台输出:“a(5)b(4)c(3)d(2)e(1)" -
分析:
我们可以把结果分成几个部分来看: a(5),b(4),c(3),d(2),e(1)每一个部分可以看成是:字符和字符对应的次数组成这样的数据,我们可以通过HashMap集合来存储,键是字符,值是字符出现的次数
//注意:键是字符,类型应该是Character;值是字符出现的次数,类型应以是Integer
- 思路:
- 键盘录入一个字符串
- 创建HashMap集合,键是Character,值是lnteger
- 遍历字符串,得到每一个字符
- 拿得到的每一个字符作为键到HashMap集合中去挖对应的值,看其返回值
如果返回值是null:说明该字符在HashMap集合中不存在,就把该字符作为键,1作为值存储,如果返回值不是null: 说明该字符在HashMap集合中存在,把该值加1,然后重新存储该字符和对应的值 - 遍历HashMap集合,得到键和值,按照要求进行拼接
package Maps;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class MapDemo4 {
public static void main(String[] args) {
System.out.print("请输入字符串:");
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String[] l = s.split("");
Map<String,Integer> m = new HashMap<String, Integer>();
for(String s1:l){
if (m.get(s1)==null){
m.put(s1,1);
}
else{
m.put(s1,m.get(s1)+1);
}
}
Set<Map.Entry<String, Integer>> entries = m.entrySet();
for(Map.Entry<String, Integer>me:entries){
System.out.print(me.getKey()+"("+me.getValue()+")");
}
}
}
52.Collections
1 Collections概述和使用
Collections类的概述:是针对集合操作的工具类
Collections类的常用方法
方法名 | 说明 |
---|---|
public static <T extends Comparable<? superT>> void sort(Listlist): | 将指定的列表按升序排序 |
public static void reverse(List<?>list): | 反转指定列表中元素的顺序 |
public static void shuffle(List<?>list): | 使用默认的随机源随机排列指定的列表 |
package Collectionss;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(20);
list.add(89);
list.add(10);
list.add(50);
// Collections.sort(list); //升序
// System.out.println(list); //[10, 20, 50, 89]
// Collections.reverse(list); //反转
// System.out.println(list); //[50, 10, 89, 20]
Collections.shuffle(list); //随机置换(洗牌)
System.out.println(list); //[10, 20, 89, 50]
}
}
2 案例:ArrayList存储学生对象并排序
需求: ArrayList存储学生对象,使用Collections对ArrayList进行排序
要求: 按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
思路:
- 定义学生类
- 创建ArrayList集合对象
- 创建学生对象
- 把学生添加到集合
- 使用Collections对ArrayList集合排序遍历集合
package Collectionss;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class CollectionsSortStudent {
public static void main(String[] args) {
ArrayList<Student> arrayList = new ArrayList<Student>();
Student s1 = new Student("nini",15);
Student s2 = new Student("coco",23);
Student s3 = new Student("vivi",10);
Student s4 = new Student("longjid",15);
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
arrayList.add(s4);
Collections.sort(arrayList, new Comparator<Student>() {
@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;
}
});
for(Student s:arrayList){
System.out.println(s.getName()+" "+s.getAge());
}
}
}
3. 模拟斗地主
Java学习笔记: