常用类1
一. 比较器
Comparator 和 Comparable 比较:
1.Comparable是排序接口;若一个类实现了Comparable接口,就意味着“该类支持排序”。
(作用在实体类上)
2.而Comparator是比较器;我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
(作用在排序类上)
总结:Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。
Comparable 内部比较器
public class House implements Comparable<House>{
private double area;
private double money;
public House(double area, double money) {
this.area = area;
this.money = money;
}
public House() {
}
public double getArea() {
return area;
}
public void setArea(double area) {
this.area = area;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "House{" +
"area=" + area +
", money=" + money +
'}';
}
@Override
public int compareTo(House o) { //1 0 -1
return Double.compare(this.getArea(),o.getArea()) ;
}
}
public class TestHouse {
public static void main(String[] args) {
House[] houses = {
new House(100,200),
new House(80.5,150),
new House(90,180),
new House(110,120),
new House(60,90)
};
//传统方式排序 报错
Arrays.sort(houses);//升序
System.out.println(Arrays.toString(houses));
//比较器排序
}
}
[House{area=60.0, money=90.0}, House{area=80.5, money=150.0}, House{area=90.0, money=180.0}, House{area=100.0, money=200.0}, House{area=110.0, money=120.0}]
Comparator 外部比较器
public class Dog {
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public Dog() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class MyComparator implements Comparator<Dog> {
/*@Override //年龄比较
public int compare(Dog o1, Dog o2) {
return o1.getAge()-o2.getAge();
}*/
//名字比较
@Override
public int compare(Dog o1, Dog o2) {
return o1.getName().compareTo(o2.getName());
}
}
public class TestDog {
public static void main(String[] args) {
Dog[] dogs={
new Dog("凤凤",5),
new Dog("牛牛",10),
new Dog("卡卡",3),
new Dog("拉拉",7),
new Dog("汪汪",2)
};
Arrays.sort(dogs,new MyComparator());
System.out.println(Arrays.toString(dogs));
}
名字比较
[Dog{name='凤凤', age=5}, Dog{name='卡卡', age=3}, Dog{name='拉拉', age=7}, Dog{name='汪汪', age=2}, Dog{name='牛牛', age=10}]
1. 成员内部类
定义在类中,充当类的一个成员。
访问权限:内部类可以访问外部类的属性和方法,外部类想要访问内部类的成员必须先创建内部类的对象来访问。
创建对象:new Outer().new Inner()
public class Outer {
//外部类的 属性方法
int a=1;
public void show(){
System.out.println("外部类的show方法");
}
//外部类调用用内部类的成员
public static void main(String[] args) {
System.out.println(new Outer().new Inter().a);
new Outer().new Inter().show();
}
public class Inter{
int a=2;
public void show(){
System.out.println("内部类的show方法");
System.out.println(new Outer().a);
new Outer().show();
}
}
}
2
内部类的show方法
1
外部类的show方法
2. 静态内部类
静态内部类可以理解为类的一个静态成员。
静态内部类不需要依赖于外部类的对象,可以直接创建自己的对象。
不能访问外部类的非static成员属性或方法,因为静态内部类不依赖外部对象,就可以自己创建对象,所以如果没有外部对象,就调用外部的实例成员,就产生了矛盾,因为外部的实例成员必须要有外部对象。
public class Outer2 {
int a=5;
static int b=9;
public void show1(){
System.out.println("外部类的实例方法");
}
public static void show2(){
System.out.println("外部类的静态方法");
}
//外部类调用内部类的属性和方法
public static void main(String[] args) {
System.out.println(new Outer2().a);
new Outer2().show1();
Outer2.show2();
new Inner().show1();
Inner.show2();
}
//静态内部类
static public class Inner{
int a=55;
static int b =99;
public void show1(){
System.out.println("内部类的实例方法");
}
public static void show2(){
System.out.println("内部类的静态方法");
}
//内部类带调用外部类的成员
public static void main(String[] args) {
//调用外部和内部的实例属性和方法
System.out.println(new Outer2().a);//外部
new Outer2().show1();
System.out.println(new Inner().a);//内部
new Inner().show1();
System.out.println("--------------------------------");
//调用外部或者内部的静态属性和方法
System.out.println(Outer2.b);//外部
Outer2.show2();
System.out.println(Inner.b);//内部
Inner.show2();
}
}
}
5
外部类的实例方法
55
内部类的实例方法
--------------------------------
9
外部类的静态方法
99
内部类的静态方法
3. 局部内部类
定义在方法中,充当方法的一个变量,注意: 局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的。
this表示当前类,包含最近的类
this前面加类名,表示查找的范围
public class Outer3 {
int a=3;
static int b=99;
public void show(){}
public void show1(){
Outer3.this.show1();
this.show1();
int a=5;
class Inner1{//地位等同于局部变量
int a=6;
public void show(){}
public void show1(){
Outer3.this.show1();
Inner1.this.show1();
this.show();
show();
this.show1();
/*this表示当前类,包含最近的类
this前面加类名,表示查找的范围*/
//内部调用外部
System.out.println(a);
System.out.println(new Outer3().a);
//new Outer3().show();
Outer3.this.show(); //
System.out.println("内部类的show");
}
}
//外 调 内
new Inner1().show1();
}
public static void main(String[] args) {
new Outer3().show1(); //调外部
}
}
4. 匿名内部类
匿名内部类,通常作为方法传参时使用,用于继承抽象类或实现接口,代替子类或实现类,并不需要额外定义方法。Jdk8开始可以使用Lambda表达式进行简化。
参考:https://mp.weixin.qq.com/s/7oiqyizsusMqwno5tDSVCA
Lambda表达式进行简化
p.setInkBox(()->"彩色");
p.setPaper(()->"A4");
public class Printer {
private InkBox inkBox;
private Paper paper;
public InkBox getInkBox() {
return inkBox;
}
public void setInkBox(InkBox inkBox) {
this.inkBox = inkBox;
}
public Paper getPaper() {
return paper;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public void show(){
System.out.println("使用"+inkBox.type()+"墨盒,在"+paper.size()+"纸张上打印");
}
}
public interface InkBox {
String type();
}
public interface Paper {
String size();
}
//匿名内部类
public class Test {
public static void main(String[] args) {
Printer p = new Printer();
/* p.setInkBox(new InkBox() {
@Override
public String type() {
return "black";
}
});*/
//Lambda表达式进行简化
p.setInkBox(()->"彩色");
p.setPaper(()->"A4");
/*p.setPaper(new Paper() {
@Override
public String size() {
return "A4";
}
});*/
p.show();
}
}
匿名内部类实现
public abstract class Handset {
//普通属性
private String brand;
private String type;
//功能接口属性
private Network network;
private PlayWriting playWriting;
private TakePicture takePicture;
//抽象方法
public abstract void senInfo();
public abstract void call();
//info方法
public void info(){
System.out.println("这是一款型号为"+type+"的"+brand+"手机");
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Network getNetwork() {
return network;
}
public void setNetwork(Network network) {
this.network = network;
}
public PlayWriting getPlayWriting() {
return playWriting;
}
public void setPlayWriting(PlayWriting playWriting) {
this.playWriting = playWriting;
}
public TakePicture getTakePicture() {
return takePicture;
}
public void setTakePicture(TakePicture takePicture) {
this.takePicture = takePicture;
}
}
接口
public interface Network {
void networkConn();
}
public interface PlayWriting {
void play(String content);
}
public interface TakePicture {
void takePicture();
}
public class Test {
public static void main(String[] args) {
//构造普通手机
Handset h = new Handset() {
@Override
public void senInfo() {
System.out.println("开始发送带文字信息。。。");
}
@Override
public void call() {
System.out.println("开始拨打语音电话。。。");
}
};
//赋值
h.setBrand("索尼");
h.setType("G099G");
h.setPlayWriting(new PlayWriting() {
@Override
public void play(String music) {
System.out.println("开始播放"+music);
}
});
//输出
h.info();
h.getPlayWriting().play("热血");
h.senInfo();
h.call();
System.out.println("---------------------------");
//智能手机
h=new Handset() {
@Override
public void senInfo() {
System.out.println("开始发送带图片与文字信息。。。");
}
@Override
public void call() {
System.out.println("开始视频通话。。。");
}
};
//赋值
h.setBrand("小米");
h.setType("小米11Ultra");
h.setPlayWriting(new PlayWriting() {
@Override
public void play(String video) {
System.out.println("开始播放视频《"+video+"》");
}
});
h.setNetwork(new Network() {
@Override
public void networkConn() {
System.out.println("连上5G网络");
}
});
h.setTakePicture(new TakePicture() {
@Override
public void takePicture() {
System.out.println("拍照");
}
});
//调用
h.info();
h.getPlayWriting().play("小时代");
h.getNetwork().networkConn();
h.getTakePicture().takePicture();
h.senInfo();
h.call();
}
}
这是一款型号为G099G的索尼手机
开始播放热血
开始发送带文字信息。。。
开始拨打语音电话。。。
---------------------------
这是一款型号为小米11Ultra的小米手机
开始播放视频《小时代》
连上5G网络
拍照
开始发送带图片与文字信息。。。
开始视频通话。。。
三. 包装类
1.包装类的概念
由于基本数据类型没有类和对象的概念,java的设计理念是万事万物皆对象。
所以特定为每一种基本数据类型量身定制了一个属于自己的类,称为包装类。
2.包装类的应用
由于集合中不能存储基本数据类型,我们所看到的 list.add(6);事实上存储的都是包装类型,由基本数据类型升级成包装类的过程叫做“装箱”,反之称为“拆箱”;
1.装箱—拆箱 包装类 –基本数据类型 自动进行
2.向上转型—向下转型 父类—子类
3.强制类型转换—自动转换 byte-short-int-long float-double
3.包装类的构造方法
1.所有包装类都可将与之对应的基本数据类型作为参数,来构造它们的实例
2.除Character类外,其他包装类可将一个字符串作为参数构造它们的实例
注意事项
- Boolean类构造方法参数为String类型时,若该字符串内容为true(不考虑大小写),则该Boolean对象表示true,否则表示false
- 当Number包装类(除了Character和Boolean其它的包装类)构造方法参数为String 类型时,字符串不能为null,且该字符串必须可解析为相应的基本数据类型的数据,否则编译不通过,运行时会抛出NumberFormatException异常
总结:
1.包装类的构造方法一般都有重载,一个构造方法的参数是对应的基本数据类型,另一个构造方法的参数是字符串类型。
4.包装类的常用方法
包装类和基本数据类型之间的区别在于 (创建对象)
- 构造方法----装箱 由基本数据类型升级成包装类的过程叫做“装箱”,反之称为“拆箱”;
//1.构造方法----装箱
/* 由基本数据类型升级成包装类的过程叫做“装箱”,反之称为“拆箱”;*/
Integer i1 = new Integer(6);
Integer i2 = new Integer("123");
Double d = new Double("12");
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean(false);
Character c = new Character('w');
- (实例方法):XXXValue():包装类转换成基本类型
//2.实例方法:xxxValue----拆箱
int i=i1.intValue();
boolean b=b1.booleanValue();
char c1=c.charValue();
- 静态方法:toString():以字符串形式返回包装对象表示的基本类型数据(基本类型->字符串)
String s = Integer.toString(6);
String s1 = Double.toString(5.6);
- 静态方法:parseXXX():把字符串转换为相应的基本数据类型数据(Character除外)(字符串->基本类型)
int i3 = Integer.parseInt("5");
double v = Double.parseDouble("2");
boolean aTrue = Boolean.parseBoolean("true");
- 静态方法:compare() 比较,返回int类型
int compare1 = Double.compare(6.2, 93.9);
System.out.println(compare1);
int compare2 = Boolean.compare(true, false);
System.out.println(compare2);
int compare3 = Character.compare('q', 'p');
System.out.println(compare3);
-1
1
1
- valueOf()(静态方法)
(1) 所有包装类都有如下方法(基本类型->包装类)
public static Type valueOf(type value)
(2) 除Character类外,其他包装类都有如下方法(字符串->包装类)
public static Type valueOf(String s)
Integer ii = Integer.valueOf(6);
Double ad = Double.valueOf(3.6);