Java入门进阶
文章目录1、常用API1.1、Math1.2、System1.3、Object1.4、Arrays1.5、基本类型包装类1.6、日期类1.7、String1.8、StringBuilder1.9、Scanef1.10、Random1.11、Scanner1、常用API1.1、Math方法名说明public static int abs(int a)返回参数的绝对值public static dou
1、常用API
1.1、Math
方法名 | 说明 |
---|---|
public static int abs(int a) | 返回参数的绝对值 |
public static double ceil(double a) | 返回大于或等于参数的最小double的值,等于一个整数 |
public static floor(double a) | 返回小于或等于参数的最大double值,等于一个整数 |
public static int round(float a) | 按四舍五入返回最接近参数的int |
public static int max(int a,int b) | 返回两个int值中的较大值 |
public static int min(int a,int b) | 返回两个int值中的较小值 |
public static double pow(double a,double b) | 返回a的b次幂的值 |
public static double random() | 返回double的正值[0.0,1.0) |
示例:
public class MathDemo {
public static void main(String[] args) {
// public static int abs(int a) 返回参数的绝对值
System.out.println(Math.abs(88));
System.out.println(Math.abs(-88));
System.out.println("*************");
// public static double ceil(double a) 返回大于或等于参数的最小double的值,等于一个整数
System.out.println(Math.ceil(9.4));//输出10.0
System.out.println(Math.ceil(9.5));//输出10.0
System.out.println("*************");
// public static floor(double a) 返回小于或等于参数的最大double值,等于一个整数
System.out.println(Math.floor(9.4));//输出9.0
System.out.println(Math.floor(9.5));//输出9.0
System.out.println("*************");
// public static int round(float a) 按四舍五入返回最接近参数的int
System.out.println(Math.round(9.4F));//输出9
System.out.println(Math.round(9.5F));//输出10
System.out.println("*************");
// public static int max(int a,int b) 返回两个int值中的较大值
System.out.println(Math.max(2,8));
System.out.println("*************");
// public static int min(int a,int b) 返回两个int值中的较小值
System.out.println(Math.min(2,8));
System.out.println("*************");
// public static double pow(double a,double b) 返回a的b次幂的值
System.out.println(Math.pow(2,3));//输出8.0
System.out.println("*************");
// public static double random() 返回double的正值[0.0,1.0)
System.out.println(Math.random());//[0.0,1.0)
System.out.println((int)(Math.random()*100));//[1,99)之间的随机int数
System.out.println((int)(Math.random()*100)+1);//[1,100)之间的随机int数
System.out.println((int)(Math.random()*91)+10);//[10,100)之间的随机int数
}
}
1.2、System
- System包含几个有用的类字段和方法,它不能被实例化。
System类的常用方法:
方法名 | 说明 |
---|---|
public static void exit(int status) | 终止当前运行的Java虚拟机,非零表示异常终止。 |
public static long currentTimeMillis() | 返回当前时间(以毫秒为单位) |
1.3、Object
方法名 | 说明 |
---|---|
toString() | 建议所有子类覆盖此方法。 |
public boolean equals(Object obj) | 比较对象是否相等。默认比较地址,重写可以比较内容。 |
1.4、Arrays
- Arrays类包含用于操作数组的各种方法:
方法名 | 说明 |
---|---|
public static String toString(int[] a) | 返回指定数组的内容的字符串表示形式 |
public static void sort(int[] a) | 按照数字顺序排序指定的数组 |
工具类的设计思想:
- 构造方法用private修饰,主要是不让外部创建对象。
- 成员用public static修饰,主要是让外部可以用类名调用。
1.5、基本类型包装类
1.5.1、基本类型包装类概述
- 将基本类型封装成对象的好处在于可以在对象中定义更多的功能方法操作数据。
- 常用的操作之一:用于将基本数据类型与字符串之间的转换。
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
doube | Double |
char | Character |
boolean | Boolean |
1.5.2、Integer
- 包装一个对象中的原始类型int的值。
方法名 | 说明 |
---|---|
public Integer(int value) | 根据int值创建Integer对象(已过时) |
public Integer(String s) | 根据String值创建Integer对象(已过时) |
public static Integer valueOf(int i) | 返回表示指定的int值的Integer实例 |
public static Integer valueOf(String s) | 返回一个保存指定值的Integer对象String |
1.5.3、int和String相互转换
int转String
/*int转String*/
int number=100;
//方式一:
String s=""+number;
//方式二:
String s1=String.valueOf(number);
String转int
/*String转int*/
String s="100";
//方式一:String转Integer转int
Integer i=Integer.valueOf(s);
int x=i.intValue();
//方式二:
int y=Integer.parseInt(s);
1.5.4、自动装箱和拆箱
-
装箱:把基本数据类型转换为对应的包装类类型。
//装箱 Integer i=Integer.valueOf(100); Integer j=100;//自动装箱,JDK5以后简化成了此种写法。
-
拆箱:把包装类类型转换为对应的基本数据类型。
//拆箱 Integer i=100;//拆箱 ii=ii.intValue()+1;//ii.intValue()是拆箱 ii+=1;// 自动拆箱
注意: 使用包装类类型时,若操作,最好先判断是否为null
只要是对象,使用前必须进行不为null的判断。
1.6、日期类
1.6.1、Date类
- Date代表了一个特定的时间,精确到毫秒
方法名 | 说明 |
---|---|
public Date() | 分配一个Date对象,并初始化,以代表它被分配到的时间,精确到毫秒 |
public Date (long date) | 分配一个Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数 |
public long getTime() | 获取的是日期对象从1970年1月1日00:00:00到现在的毫秒值 |
public void setTime(long time) | 设置时间,给的是毫秒值 |
1.6.2、SimpleDateFormat类
- 用于日期格式化和解析。
方法名 | 说明 |
---|---|
pubblic SimpleDateFormat() | 构造一个SimpleDateFormat,使用默认模式和日期格式 |
public SimpleDateFormat(String pattern) | 构造一个SimpleDateFormat模式使用给定的模式和默认的日期格式 |
1.6.2.1、格式化(从Date到String)
public final format(Date date)
:将日期格式化成日期/时间字符串
默认格式
import java.util.Date;
import java.text.SimpleDateFormat;
public class SimpleDateFormatDemo {
public static void main(String[] args) {
Date d=new Date();
SimpleDateFormat sdf=new SimpleDateFormat();
String s=sdf.format(d);
System.out.println(s);
}
}
指定格式
Date d=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String t=sdf.format(d);
System.out.println(t);
1.6.2.2、解析(从String到Date)
public Date parse(String source)
:从给定字符串的开始解析文本生成日期
import java.text.ParseException;
import java.util.Date;
import java.text.SimpleDateFormat;
public class SimpleDateFormatDemo {
public static void main(String[] args) throws ParseException {
String t="2022-02-28 12:00:01";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d=sdf.parse(t);
System.out.println(d);
}
}
1.6.3、Calendar类
- Calendar提供了一个类方法getInstance用于获取Calendar对象,其日历字段已使用当前日期和时间初始化:
Calendar rightNow=Calendar.getInstance();
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 date=c.get(Calendar.DATE);
System.out.println(year+"年"+month+"月"+date+"日");
}
}
Calendar常用方法:
方法名 | 说明 |
---|---|
public int get(int field) | 返回给定日历字段的值 |
public abstract void add(int field,int amount) | 根据日历的规则,将指定的时间量添加或减去给定的日历字段 |
public final void set(int year,int month,int date) | 设置当前日历的年月日 |
import java.util.Calendar;
public class CalendarDemo {
public static void main(String[] args) {
Calendar c=Calendar.getInstance();
//public abstract void add(int field,int amount)
c.add(Calendar.YEAR,-2);//两年前
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+"日");
// public final void set(int year,int month,int date)
c.set(2000,0,1);//将日历设置为2000-1-1
year=c.get(Calendar.YEAR);
month=c.get(Calendar.MONTH)+1;//月份从0开始
date=c.get(Calendar.DATE);
System.out.println(year+"年"+month+"月"+date+"日");
}
}
二月天案例:
import java.util.Scanner;
import java.util.Calendar;
public class CalendarDemo {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入年份:");
int year=sc.nextInt();
Calendar c=Calendar.getInstance();
//将日历设置为3月1日,再减一天就是2月的最后一天
c.set(year,2,1);
c.add(Calendar.DATE,-1);
int date=c.get(Calendar.DATE);
System.out.println(year+"年二月有"+date);
}
}
1.7、String
1.8、StringBuilder
1.9、Scaner
1.10、Random
2、异常
2.1、异常概述
- 异常:就是程序出现了不正常的情况
- Error:严重问题,不需要处理
- Exception:称为异常类,它表示程序本身可以处理的问题。
- RuntimeException:在编译期是不检查的,出现问题后,需要我们回来修改代码。
- 非RuntimeException:编译期就必须处理,否则程序不能通过编译。
2.2、JVM的默认处理方案
如果程序出现 问题,我们没有做任何处理,最终JVM会做默认的处理。
- 把异常的名称,异常原因及异常出现的位置等信息输出在了控制台。
- 程序停止执行。
2.3、异常处理
如果程序出现了问题,我们需要自己来处理,有两种方案:
try...catch...
throws
格式:
try{
可能出现异常的代码;
}catch(异常类名 变量名){
异常处理代码;
}
执行流程:
- 程序从try里面的代码开始执行。
- 出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统。
- 当Java运行时系统接收异常对象时,会到catch中云找匹配的异常类,找到后进行异常的处理。
- 执行完毕后,程序还可继续往下执行。
2.4、异常处理之try…catch…
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("开始");
methood();
System.out.println("异常处理完毕仍可继续运行");
}
public static void methood(){
try{
int[] arr={1,2,3};
System.out.println(arr[3]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("数组下标越界");
e.printStackTrace();
}
}
}
2.5、Throwable的成员方法
方法名 | 说明 |
---|---|
public String getMessage() | 返回此throwable的详细消息字符串 |
public String toString() | 返回此可抛出的简短描述 |
public void printStackTrace() | 把异常的错误信息输出在控制台 |
2.6、编译时异常和运行时异常的区别
- Java中的异常被分为两大类:编译时异常和运行时异常,也被称为受检异常和非受检异常。
- 所有的RuntimeException类及其子类被称为运行时异常,其他的异常都是编译时异常。
编译时异常: 必须显示处理,否则程序就会发生错误,无法通过编译。
运行时异常: 无需显示处理,也可以和编译时异常一样处理。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("开始");
methood();
System.out.println("结束");
}
public static void methood(){
try{
String s="2000-01-01";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date d=sdf.parse(s);
}catch (ParseException e){
e.printStackTrace();
}
}
}
2.7、异常处理之throws
虽然可以通过try…catch…对异常处理,但并不是所有情况都有权限进行异常的处理。即,有些时候可能出现的异常我们处理不了。
针对这种情况,Java提供了throws的处理方案。
格式:
throws 异常类名;
注意:这个格式是跟在方法的括号后面的。
- 编译时异常必须要进行处理,两种处理方案:
try...catch....
或者throws
,将来谁调用谁处理。 - 运行时异常可以不处理,出现问题后,需要回来修改代码。
//编译时异常
public static void methood() throws ParseException {
String s="2000-01-01";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date d=sdf.parse(s);
}
//运行时异常
public static void methood1() throws ArrayIndexOutOfBoundsException{
int arr[]={1,2,3};
System.out.println(arr[3]);
}
2.8、自定义异常
格式:
public class 异常类名 extends Exception{
无参构造
带参构造
}
示例:
- 自定义异常类
//自定义异常类 package com.test1; public class ScoreException extends Exception { public ScoreException(){} public ScoreException(String message){ super(message); } }
- 抛出异常。
package com.test1; public class Score{ public static void check(int score) throws ScoreException{ if(score<0||score>100){ throw new ScoreException("分数不在0-100之间"); }else{ System.out.println("分数正常"); } } }
- 处理异常
package com.test1; import java.util.Scanner; public class ScoreDemo { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System.out.println("请输入分数:"); int score=sc.nextInt(); try{ Score.check(score); }catch(ScoreException e){ e.printStackTrace(); } } }
注意:
- 运行时异常类继承自:
RuntimeException
。 - 编译时异常类继承自
Exception
。
2.9、throws和throw的区别
throws
- 用在方法声明后,跟的是异常类名。
- 表示抛出异常,由该方法的调用者来处理。
- 表示出现异常的一种可能性,并不一定发生这些异常。
throw - 用在方法体内,跟的是异常对象名。
- 表示抛出异常,由方法体内的语句处理。
- 执行throw一定抛出了某种异常。
3、集合进阶
集合体系结构
3.1、Collection
- 是单列集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素。
- JDK不提供此接口的任何直接实现,它提供更具体的子接口实现,如
Set
和List
。
创建Collection集合的对象:
- 多态的方式
- 具体的实现类ArrayList
import java.util.Collection;
import java.util.ArrayList;
public class CollectionDemo {
public static void main(String[] args) {
Collection<String> c=new ArrayList<String>();
c.add("Hello");
c.add("world");
System.out.println(c);
}
}
Collection集合常用方法:
方法名 | 说明 |
---|---|
boolea:n add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定的元素 |
void clear() | 清空集合中的元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中元素的个数 |
Collection集合的遍历:
- Iterator:迭代器,集合的专用 遍历方式。
- Iteratoriterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到。
- 迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合面存在的。
Iterator中的常用方法:
- E next():返回迭代中的下一个元素。
- boolean hasNext():如果迭代具有更多元素,则返回true
import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String[] args) {
Collection<String> c=new ArrayList<String>();
c.add("Hello");
c.add("world");
c.add("java");
Iterator<String> it=c.iterator();
while(it.hasNext()){
String s=it.next();
System.out.println(s);
}
}
}
3.2、List
3.2.1、List
List集合概述
- 有序集合(也称序列),用户可精确控制列表中每个元素的插入位置。用户可通过索引访问元素。
- 与Set集合不同,列表通常允许重复的元素。
List集合特点
- 有序:存储和取出的元素顺序一致。
- 可重复:存储的元素可以重复。
List集合特有方法:
方法名 | 说明 |
---|---|
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
示例:
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
public class ListDemo {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("Hello");
list.add("world");
list.add("java");
//第一种遍历:迭代器遍历
Iterator<String> it=list.iterator();
while(it.hasNext()){
String s=it.next();
System.out.println(s);
}
//第二种遍历:for循环方式
for(int i=0;i<list.size();i++){
String s=list.get(i);
System.out.println(s);
}
}
}
3.2.2、List并发修改异常
并发修改异常
ConcurrentModificationException
产生原因
- 迭代器遍历的过程中,通过集合对象修改了集合中元素的长度,造成了迭代器猎取元素中判断预期修改值和实际值不一致。
解决方案:
- 用for循环遍历,然后用集合对象做对应的操作即可。
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
public class ListDemo {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("Hello");
list.add("world");
list.add("java");
//第一种遍历:迭代器遍历
Iterator<String> it=list.iterator();
while(it.hasNext()){
String s=it.next();//触发并发修改异常
if(s.equals("world")){
list.add("aaa");
}
}
//用for循环方式遍历可解决List并发修改异常的问题:
for(int i=0;i<list.size();i++){
String s=list.get(i);
if(s.equals("world")){
list.add("aaa");
}
}
}
}
3.2.3、ListIterator
ListIterator列表迭代器
- 通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器。
- 可沿任一方向遍历列表的列表迭代器,迭代期间修改列表,并获取列表中迭代器的当前位置。
ListIterator中的常用方法:
E next()
:返回迭代中的下一下元素。boolean hasNext()
:如果迭代具有更多元素,则返回true。E previous()
:返回列表中的上一个元素。boolean hasPrevious()
:如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回true。void add(E e)
:将指定的元素插入列表。
import java.util.List;
import java.util.ArrayList;
import java.util.ListIterator;
public class ListIteratorDemo {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("java");
ListIterator<String> lit=list.listIterator();
while(lit.hasNext()){
String s=lit.next();
System.out.println(s);
}
System.out.println("---------");
while(lit.hasPrevious()){
String s = lit.previous();
System.out.println(s);
}
}
}
ListIterator不触发并发修改异常
import java.util.List;
import java.util.ArrayList;
import java.util.ListIterator;
public class ListIteratorDemo {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("java");
ListIterator<String> lit=list.listIterator();
while(lit.hasNext()){
String s = lit.next();
if(s.equals("world"))
lit.add("javaEE");
}
System.out.println(list);
}
}
3.2.4、增加for循环
- 简化数组和Collection集合的遍历。
- 实现Iterable接口的类允许其对象成为增强型for语句的目标
- JDK5之后出现,其内部原理是一个Iterator迭代器。
增强for的格式:
for(元素的数据类型变量名:数组或者Collection集合){
//在此处使用变量即可,该变量就是元素。
}
示例:
int[] arr={1,2,3,4,5};
for(int i:arr){
System.out.println(i);
}
3.2.5、数据结构
3.2.5.1、栈
- 先进后出。
3.2.5.2、列
- 先进先出。
3.2.5.3、数组
- 数组是一种查询快,增删慢的模型。
- 查询数据通过索引定位,查询任意数据耗时相同,查询速度快。
- 删除数据时,要将原始数据删除,同时后面两个数据前移,删除效率低。
- 添加数据时,添加位置后的每人数据后移,再添加元素,添加效率极低。
3.2.5.4、链表
- 链表是一种增删快的模型(对比数组)。
- 链表是一种查询慢的模型(对比数组)。
- 查询数据是否存在,必须从头(head)开始查询 。
3.2.6、List集合子类特点
List集合常用子类:ArrayList
、LinkedList
- ArrayList:底层数据结构是数组,查询快,增删慢
- LinkedList:底层数据结构是链表,查询慢,增删快。
ArrayList集合的三种遍历方式
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.ListIterator;
public class test6 {
public static void main(String[] args) {
ArrayList<String> array=new ArrayList<String>();
array.add("Hello");
array.add("world");
array.add("java");
for(String s:array){
System.out.println(s);
}
System.out.println("************");
for(int i=0;i<array.size();i++){
String s=array.get(i);
System.out.println(s);
}
System.out.println("************");
ListIterator<String> it=array.listIterator();
while(it.hasNext()){
String s=it.next();
System.out.println(s);
}
System.out.println("************");
while(it.hasPrevious()){
String s=it.previous();
System.out.println(s);
}
//LinkedList与ArrayList三种遍历方法相同
LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("aaa");
linkedList.add("bbb");
linkedList.add("ccc");
for(String s:linkedList){
System.out.println(s);
}
}
}
3.2.7、LinkedList集合的特有功能
方法名 | 说明 |
---|---|
puclic void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
3.3、Set
3.3.1、Set集合概述和特点
Set集合特点
- 不包含重复元素的集合。
- 没有带索引的方法,所以不能使用普通for循环遍历。
import java.util.Set;
import java.util.HashSet;
public class SetDemo {
public static void main(String[] args) {
Set<String> set=new HashSet<String>();
set.add("Hello");
set.add("world");
set.add("java");
//没有带索引的方法,所以不能使用普通for循环遍历
//只能使用增强for循环遍历
for(String s:set){
System.out.println(s);
}
}
}
3.3.2、哈希值
哈希值: 是JDK根据对象的地址或者字符串或者数字计算出来的int类型的数值。
Object
类中有一个方法可获取对象的哈希值:
public int hashCode():
返回对象的哈希值。
对象的哈希值特点
- 同一个对象多次调用
hashCode()
方法返回的哈希值是相同的。 - 默认情况下,不同对象的哈希值是不相同的。
- 通过重写
Object
中的hashCode
方法,可以实现不同对象的哈希值是相同的。
3.3.3、HashSet集合添加一个元素的过程
HashSet集合存储元素:
- 要保证元素唯一性,需要重写
hashCode()
和equals()
3.3.4、哈希表
- JDK8之前,底层采用
数组+链表
实现,可以说是一个元素为链表的数组。 - JDK8以后,在长度比较长的时候,底层实现了优化。
3.3.5、LinkedHashSet
LinkedHashSet集合特点:
- 哈希表和链表实现的Set接口,具有可预测的迭代次序。
- 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的。
- 由哈希表保证元素唯一,也就是说没有重复的元素经。
import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
public static void main(String[] args) {
LinkedHashSet<String> linkedHashSet=new LinkedHashSet<String>();
linkedHashSet.add("Hello");
linkedHashSet.add("world");
linkedHashSet.add("java");
for(String s:linkedHashSet){
System.out.println(s);
}
}
}
3.3.6、TreeSet
TreeSet集合特点
- 元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法。
- TreeSet()根据其元素的自然排序进行排序。
- TreeSet(Comparator comparator)根据指定的比较器进行排序
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以不包含有重复元素的集合
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Integer> treeSet=new TreeSet<Integer>();
treeSet.add(10);
treeSet.add(50);
treeSet.add(30);
treeSet.add(20);
treeSet.add(40);
for(Integer i:treeSet){
System.out.println(i);
}
}
}
3.3.7、自然排序Comparable的使用
- 存储学生对象并遍历,创建TreeSet集合使用无参构造方法。
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母排序。
结论:
- Student类不实现
Comparable
接口,会触发ComparablClassCastException
异常。 - 实现
Comparable
接口就必须要实现compareTo(T o)
方法。
compareTo(T o)
方法的返回值:
- 返回0,会认为是重复元素不添加(添加的第一个元素除外)
- 返回正数,按存储的顺序正着输出。
- 返回负数,按存储的顺序倒着输出。
//Student.java
public class Student implements Comparable<Student> {
private String name;
private int age;
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; //会认为是重复元素不添加进TreeSet(添加的第一个元素除外)
return 1;//按存储的顺序升序输出。
return -1;//按存储的顺序倒着输出。
*/
/*
//按照年龄从小到大排序
return this.age-s.age;
//按照年龄从大到小排序
return s.age-this.age;
*/
int num=this.age-s.age;
return num==0?this.name.compareTo(s.name):num;
}
}
//TreeSetDemo.java
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> treeSet=new TreeSet<Student>();
Student s1=new Student("bbb",20);
Student s2=new Student("aaa",20);
Student s3=new Student("ccc",21);
Student s4=new Student("ddd",30);
Student s5=new Student("eee",19);
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
treeSet.add(s4);
treeSet.add(s5);
for(Student s:treeSet){
System.out.println(s.getName()+","+s.getAge());
}
}
}
- 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的。
- 自然排序,就是让元素所属的类实现Comparable接口,重写compareTo方法。
- 重写方法时,一定要注意排序规则按要求的主要条件和次要条件来写。
3.3.8、比较器排序Comparator的使用
- 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序。
- 比较器排序,就是让集合构造方法接收Comparator的实现类对象。
- 重写方法时,一定要注意排序规则必须按照主要条件和次要条件来写。
//Studen.java
public class Student {
private int age;
private String name;
public Student( String name,int age) {
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;
}
}
//TreeSetDemo.java
import java.util.TreeSet;
import java.util.Comparator;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> treeSet=new TreeSet<Student>(new Comparator<Student>(){
@Override
public int compare(Student s1,Student s2){
int num=s1.getAge()-s2.getAge();
int num1=(0==num?s1.getName().compareTo(s2.getName()):num);
return num1;
}
});
Student s1=new Student("aaa",25);
Student s2=new Student("bbb",19);
Student s3=new Student("ddd",20);
Student s4=new Student("ccc",20);
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
treeSet.add(s4);
for(Student s:treeSet){
System.out.println(s.getName()+","+s.getAge());
}
}
}
3.4、泛型
3.4.1、泛型概述
- JDK5中引入的特性。
- 它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
- 泛型类、泛型方法、泛型接口。
import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;
public class GenericDemo {
public static void main(String[] args) {
Collection<String> c=new ArrayList<String>();
c.add("Hello");
c.add("world");
Iterator<String> it=c.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
}
}
3.4.2、泛型类
泛型的定义格式:
- 格式:
修饰符 class 类名<类型>{}
- 范例:
public class Generic<T> {}
此处T
可以随便定为任意标识,常见的如T
、E
、K
、V
//Generic.java
public class Generic<T> {
private T t;
public Generic(T t) {
this.t = t;
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
GenericDemo.java
public class GenericDemo {
public static void main(String[] args) {
Generic<String> g1=new Generic<String>("李淳罡");
System.out.println(g1.getT());
Generic<Integer> g2=new Generic<Integer>(20);
System.out.println(g2.getT());
}
}
3.4.3、泛型方法
泛型方法定义格式:
- 格式:修饰符<类型> 返回值类型 方法名(类型 变量名){}
- 范例:
pubcli <T> void show(T t){}
public class Generic<T>{
public void show(T t){
System.out.println(t);
}
}
泛型方法改进:
public class Generic{
public<T> void show(T t){
System.out.println(t);
}
}
3.4.4、泛型接口
泛型接口定义格式:
- 格式:修饰符 interface 接口名<类型>{}
- 范例:
pubcli interface Generic<T>{}
public interface Generic<T> {
void show(T t);
}
public class Genericlmpl<T> implements Generic<T> {
@Override
public void show(T t){
System.out.println(t);
}
}
public class Demo {
public static void main(String[] args) {
Generic<String> g1=new Genericlmpl<String>();
g1.show("hello");
Generic<Integer> g2=new Genericlmpl<Integer>();
g2.show(15);
}
}
3.4.5、类型通配符
类型通配符
- 为了表示各种泛型List的父类,可以使用类型通配符
- 类型通配符:
<?>
List<?>
:表示元素类型未知的List,它的元素可以匹配任何的类型- 这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中。
类型通配符上限
如果不希望List<?>
是任何泛型List的父类,只希望它代表某一类型泛型List的父类,可以使用类型通配符的上限。
- 类型通配符上限:<?extends 类型>
List<? extends Number>
:它表示的类型是Number或者其子类型
类型通配符下限
除了可以指定类型通配符的上限,还可指定类型通配符的下限
- 类型通配符下限:
<? super 类型>
List<? super Number>
:它表示的类型是Number或者其父类型
import java.util.List;
import java.util.ArrayList;
public class Demo {
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 List<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>();//报错,这里超过了下限
}
}
3.4.6、可变参数
- 格式:
修饰符 返回值类型 方法名(数据类型... 变量名){}
- 范例:
public static int sum(int... a)
public class Demo {
public static void main(String[] args) {
System.out.println(sum(1));
System.out.println(sum(1,2));
System.out.println(sum(1,2,3));
}
public static int sum(int... arr){
int total=0;
for(int i:arr){
total+=i;
}
return total;
}
}
注意:
- 这里的变量a其实是一个数组
- 如果一个方法有多个参数,可变参数要放在最后。
public static int sum(int a,int... arr){
return 0;
}
3.4.7、可变参数的使用
Arrays工具类中有一个静态方法:
-
public static<T> List<T> asList(T... a)
:返回由指定数组支持的固定大小的列表。 -
返回的集合不能做增删操作(增删会改变长度),可以做修改操作。
import java.util.Arrays; import java.util.List; public class Demo { public static void main(String[] args) { List<String> list= Arrays.asList("hello","world","java","hello"); // list.add("aaa");//UnsupportedOperationException // list.remove("hello");//UnsupportedOperationException list.set(1,"aaa"); System.out.println(list); } }
List接品中有一个静态方法:
-
public static<E> List<E> of(E... elements)
:返回包含任意数量元素的不可变列表。 -
返回的集合不能做增删改操作。
import java.util.List; public class Demo { public static void main(String[] args) { List<String> list= List.of("hello","world","hello"); // list.add("aaa");//UnsupportedOperationException // list.remove("hello");//UnsupportedOperationException // list.set(1,"aaa");//UnsupportedOperationException System.out.println(list); } }
Set接口中有一个静太方法:
-
public static<E> Set<E> of(E... elements)
:返回一个包含任意数量元素的不可变集合。 -
不能给重复的元素。
-
返回的集合不能做增删操作,没有修改的方法。
import java.util.Set; public class Demo { public static void main(String[] args) { // Set<String> set= Set.of("hello","world","hello");//IllegalArgumentException,set中不能有重复元素 Set<String> set= Set.of("hello","world"); // set.add("aaa");//UnsupportedOperationException // set.remove("hello");//UnsupportedOperationException System.out.println(set); } }
3.5、Map
3.5.1、Map集合概述
Map集合概述
Interface Map<k,v>
K:键的类型; V:值的类型。- 将键映射到值的对象;
- 不能包含重复的键;
- 每个键可以映射到最多一个值。
创建Map集合对象
- 多态的方式
- 具体实现类HashMap
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> map=new HashMap<String,String>();
map.put("001","唐僧");
map.put("002","孙悟空");
map.put("003","猪八戒");
map.put("003","沙悟净");//key重复,会被新的value覆盖
System.out.println(map);
}
}
3.5.2、Map集合的基本功能
方法名 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,即集合中键值对的个数 |
3.5.3、Map集合的获取功能
方法名 | 说明 |
---|---|
V get(Object key) | 根据键获取值 |
Set<K> keySet() | 获取所有键的集合 |
Collection<V> values() | 获取所有值的集合 |
Set<Map.Entry<K,v>> entrySet() | 获取所有键值对对象的集合 |
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<String,String>();
map.put("张无忌","赵敏");
map.put("郭靖","黄蓉");
map.put("杨过","小龙女");
System.out.println(map.get("杨过"));
System.out.println("*************");
Set<String> set=map.keySet();
for(String key:set){
System.out.println(key);
}
System.out.println("*************");
Collection<String> values=map.values();
for(String value:values){
System.out.println(value);
}
System.out.println("*************");
System.out.println(map);
}
}
3.5.4、Map集合的遍历
方式一:
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<String,String>();
map.put("张无忌","赵敏");
map.put("郭靖","黄蓉");
map.put("杨过","小龙女");
//获取所有键的集合
Set<String> keys = map.keySet();
for(String key:keys){
String value=map.get(key);
System.out.println(key+","+value);
}
}
}
方式二:
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<String,String>();
map.put("张无忌","赵敏");
map.put("郭靖","黄蓉");
map.put("杨过","小龙女");
Set<Map.Entry<String, String>> entries = map.entrySet();
for(Map.Entry<String,String> entry:entries){
String key=entry.getKey();
String value=entry.getValue();
System.out.println(key+","+value);
}
}
}
3.5.5、HashMap的案例
- 创建一个HashMap集合,键是学生对象(Student),值是居住地(String)
- 要求保证唯一性:若学生对象成员变量值相同,认为是同一对象。
//Student.java
public class Student {
private String name;
private int age;
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 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;
}
}
//HashMapDemo.java
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<Student,String> hm=new HashMap<Student,String>();
Student s1=new Student("孙悟空",30);
Student s2=new Student("猪八戒",20);
Student s3=new Student("沙悟净",20);
Student s4=new Student("孙悟空",30);
/*
s1和s4对象相同,value应该被覆盖
若要s1和s4对象相同,须重写Student类的hashCode和equals
*/
hm.put(s1,"花果山");
hm.put(s2,"高老庄");
hm.put(s3,"流沙河");
hm.put(s4,"水帘洞");
//遍历
Set<Student> students = hm.keySet();
for(Student s:students){
String value=hm.get(s);
System.out.println(s.getName()+","+
s.getAge()+",住在"+
value);
}
}
}
3.5.6、ArrayList中嵌套HashMap
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class ArrayListIncludeHashMap {
public static void main(String[] args) {
ArrayList<HashMap<String,String>> arrList=new ArrayList<HashMap<String,String>>();
HashMap<String,String> hm1=new HashMap<String,String>();
hm1.put("郭靖","黄蓉");
hm1.put("杨过","小龙女");
HashMap<String,String> hm2=new HashMap<String,String>();
hm2.put("吕布","貂蝉");
hm2.put("诸葛亮","黄月英");
HashMap<String,String> hm3=new HashMap<String,String>();
hm3.put("张无忌","赵敏");
hm3.put("宋青书","周芷若");
arrList.add(hm2);
arrList.add(hm2);
arrList.add(hm3);
for(HashMap<String,String> hm:arrList){
Set<String> keySet = hm.keySet();
for(String key:keySet){
String value=hm.get(key);
System.out.println(key+","+value);
}
System.out.println("************");
}
}
}
3.5.7、HashMap中嵌套ArrayList
3.5.8、统计字符串中每个字符出现的次数
需求:
- 键盘录入一个字符串,统计字符串中每个字符出现的次数。
- 举例:录入"aabbccdd"在控制台输出“a(2)b(2)c(2)”
思路:
- 键盘录入一个字符串
- 创建HashMap集合,键是Character,值是Integer
- 遍历字符串,得到每一个字符。
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
public class Demo {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串");
String line = sc.nextLine();
Map<Character,Integer> map=new TreeMap<Character,Integer>();
//遍历字符串,得到每一个字符
for(int i=0;i<line.length();i++){
char key=line.charAt(i);
Integer value=map.get(key);
if(null==value){
map.put(key,1);
}else{
value++;
map.put(key,value);
}
}
//遍历HashMap集合
StringBuilder sb=new StringBuilder();
Set<Character> keySet = map.keySet();
for(Character key:keySet){
Integer value=map.get(key);
sb.append(key).append("(").append(value).append(")");
}
System.out.println(sb.toString());
}
}
3.6、Collections
3.6.1、Collections的概述
- 是针对集合操作的工具类。
常用方法
public static <T extends Comparable<? super T>> void sort(List<T> list)
:将指定的列表按升序排序。public static void reverse(List<?> list)
:反转指定列表中元素的顺序。public static void shuffle(List<?> list)
:使用默认的随机源随机排列指定的列表。
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(3);
list.add(4);
list.add(1);
list.add(6);
list.add(5);
list.add(2);
//排序
Collections.sort(list);
System.out.println(list);
//反转list中的顺序
Collections.reverse(list);
System.out.println(list);
//洗牌
Collections.shuffle(list);
System.out.println(list);
}
}
3.6.2、对ArrayList排序
public class Student {
private String name;
private int age;
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;
}
}
java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Demo {
public static void main(String[] args) {
ArrayList<Student> array=new ArrayList<Student>();
Student s1=new Student("linqingxia",30);
Student s2=new Student("zhangmanyu",35);
Student s3=new Student("aaaaa",33);
Student s4=new Student("bbbb",33);
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
//使用Collectons对ArrayList集合排序
Collections.sort(array, 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:array){
System.out.println(s.getName()+","+s.getAge());
}
更多推荐
所有评论(0)