Java基本应用
包的引用
import net.jsfan.User;//方法二:定向引入包
import net.jsfan.*;//2.方法三:整体引入包
import java.util.Date;//引入自带时间包
public class Test {
public static void main(String[] args) {
net.jsfan.User user = new net.jsfan.User();//指定包的引用 1.方法一:直接引用
User aa = new User();//方法二的引用
aa.say();
Date date = new Date();
}
}
static
public class Static {
int id; // id
String name; // 账户名
String pwd; // 密码
static String company = "jsfan";
public Static(int id, String name) {
this.id = id;
this.name = name;
}
public void login() {
printCompany();//非静态可以掉静态成员
System.out.println(company);
System.out.println("登录:" + name);
}
public static void printCompany() {
// login();//静态成员调用非静态成员,编译就会报错 在static方法中不可直接访问非static的成员
System.out.println(company);
}
public static void main(String[] args) {
//通过对象调用普通方法
Static u = new Static(101, "Youngster_yj");
//通过static直接调用
Static.printCompany();
Static.company = "blog";
Static.printCompany();
}
}
代码块
public class Demo1 {
static {
System.out.println("我是在主方法类中的静态代码块");
}
public static void main(String[] args) {
{
int x = 10; //限定变量的声明周期
System.out.println(x);
}
Student s1 = new Student();
System.out.println("---------------");
Student s2 = new Student("张三",23);
}
}
class Student {
private String name;
private int age;
public Student(){
//study();
System.out.println("空参构造");
} //空参构造
public Student(String name,int age) {//有参构造
//study();
this.name = name;
this.age = age;
System.out.println("有参构造");
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
{//构造代码块:每创建一次对象就会执行一次,优先于构造函数执行
//System.out.println("构造代码块");
study();
}
public void study() {
System.out.println("学生学习");
}
static {//随着类加载而加载,且只执行一次
System.out.println("我是静态代码块");//作用:用来给类进行初始化,一般用来加载驱动
}//静态代码块是优先于主方法执行
}
/*
我是在主方法类中的静态代码块
10
我是静态代码块
学生学习
空参构造
---------------
学生学习
有参构造
*/
super
public class TestSuper {
public static void main(String[] args) {
new ChildClass().f();
}
}
class FatherClass {
public int value;
public void f(){
value = 100;
System.out.println ("FatherClass.value="+value);
}
}
class ChildClass extends FatherClass {
public int value;
public void f() {
super.f(); //调用父类对象的普通方法
value = 200;
System.out.println("ChildClass.value="+value);
System.out.println(value);
System.out.println(super.value); //调用父类对象的成员变量
}
}
//FatherClass.value=100
//ChildClass.value=200
//200
//100
public class TestSuper2 {
public static void main(String[] args) {
System.out.println("开始创建一个ChildClass对象......");
new ChildClass1();
}
}
class FatherClass1 {
public FatherClass1() {
System.out.println("创建FatherClass");
}
}
class ChildClass1 extends FatherClass1 {
public ChildClass1() {
super();//默认添加 先调用父类构造器
System.out.println("创建ChildClass");
}
}
//开始创建一个ChildClass对象......
//创建FatherClass
//创建ChildClass
重载
public class User {
int id; // id
String name; // 账户名
String pwd; // 密码
public User() {
}
public User(int id, String name) {//如果构造方法中形参名与属性名相同时,需要使用this关键字区分属性与形参。
// super(); //默认添加 先调用父类构造器 构造方法第一句总是super()
this(); // 调用无参的构造方法,并且必须位于第一行!
this.id = id;
this.name = name;
}
public User(int id, String name, String pwd) {
this(id,name);//简写 调用带参的构造方法,并且必须位于第一行!
this.id = id;
this.name = name;
this.pwd = pwd;
}
void sing() {
}
void eat() {
this.sing(); // 调用本类中的sing();
System.out.println("你妈妈喊你回家吃饭!");
}
public static void main(String[] args) {
User u1 = new User();
u1.eat();
User u2 = new User(101, "高小七");
User u3 = new User(100, "高淇", "123456");
}
}
final
- A:final概述final是最终的
- final是最终的
- B:final修饰特点修饰类,类不能被继承修饰变量,变量就变成了常量,只能被赋值一次修饰方法,方法不能被重写
- 修饰类,类不能被继承
- 修饰变量,变量就变成了常量,只能被赋值一次
- 修饰方法,方法不能被重写
键盘输入值
import java.util.Scanner;
public class keyboard {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入名字:");
String name = scanner.nextLine();
System.out.println("请输入你的爱好:");
String favor = scanner.nextLine();
System.out.println("请输入你的年龄:");
int age = scanner.nextInt();
System.out.println(name);
System.out.println(favor);
System.out.println(age);
System.out.println(name+favor+age);
}
}
比较 equals
public class TestEquals {
public static void main(String[] args) {
Person1 p1 = new Person1(123,"fan");
Person1 p2 = new Person1(123,"jsfan");
System.out.println(p1==p2); //false,不是同一个对象
System.out.println(p1.equals(p2)); //true,id相同则认为两个对象内容相同
String s1 = new String("blog");
String s2 = new String("blog");
System.out.println(s1==s2); //false, 两个字符串不是同一个对象
System.out.println(s1.equals(s2)); //true, 两个字符串内容相同
}
}
class Person1 {
int id;
String name;
public Person1(int id,String name) {
this.id=id;
this.name=name;
}
public boolean equals(Object obj) {
if(obj == null){
return false;
}else {
// instanceof是二元运算符,左边是对象,右边是类;当对象是右面类或子类所创建对象时,返回true;否则,返回false
if(obj instanceof Person1) {
Person1 c = (Person1)obj;
if(c.id==this.id) {
return true;
}
}
}
return false;
}
}
继承 extends
//子类只能继承父类所有非私有的成员(成员方法和成员变量)
//子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法
public class TestExtends {
public static void main(String[] args) {
Student stu = new Student();
stu.name="yj";
stu.height = 172;
stu.rest();//休息一会
Student stu2 = new Student("随意构造",172,"玩游戏");
System.out.println(stu2 instanceof Student);//true
System.out.println(stu2 instanceof Person);//true
System.out.println(stu2 instanceof Object);//true
// instanceof是二元运算符,左边是对象,右边是类;当对象是右面类或子类所创建对象时,返回true;否则,返回false
}
}
class Person{ /*默认继承 extends Object*/
String name;
int height;
public void rest() {
System.out.println("休息一会");
}
}
class Student extends Person{//Java中类没有多继承,接口有多继承。
//子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)
String major;
public Student() {
}
public void study() {
System.out.println("学习两小时");
}
public Student(String name,int height,String major) {
this.name = name;
this.height = height;
this.major = major;
}
}
方法重写
public class TestOverride {
public static void main(String[] args) {
Horse h = new Horse();
h.run();//到处跑,阿巴阿巴
Vehicle v3 = new Plane();
v3.run();//天上飞!
v3.stop();//空中不能停,坠毁了!
}
}
class Vehicle{
public void run() {
System.out.println("跑...");
}
public void stop() {
System.out.println("停止");
}
}
class Horse extends Vehicle{
public void run() { //1.重写(覆盖) 覆盖继承的类中的方法
System.out.println("到处跑,阿巴阿巴");
}
}
class Plane extends Vehicle {
public void run() { // 重写父类方法
System.out.println("天上飞!");
}
public void stop() {
System.out.println("空中不能停,坠毁了!");
}
}
访问控制符
public class TestPublic {
private int age;
String name;//可以被本包下面的类访问
protected int height;
public void Puc() {
System.out.println("public");
}
}
//1. private 表示私有,只有自己类能访问
//2. default表示没有修饰符修饰,只有同一个包的类能访问
//3. protected表示可以被同一个包的类以及其他包中的子类访问
//4. public表示可以被该项目的所有包中的所有类访问
import net.jsfan.TestPublic;
public class TestEncapsulation {
public static void main(String[] args) {
Human h = new Human();
// h.age = 13; 私有属性和方法不可用
h.name="yj"; //默认同一个包可使用
TestPublic pub = new TestPublic();
// pub.name="yj";默认无法跨包访问
// pub.height protected权限无法跨包直接访问
}
}
class Girl extends TestPublic{
void sayGood() {
System.out.println(height);//protected权限可以跨包继承访问
}
}
class Human{
private int age;
String name;
void sayAge() {
System.out.println(age);
}
}
class Boy extends Human{
void sayHello() {
// System.out.println(age); 私有属性和方法子类也不可用
}
}
多态
/*
1. 多态是方法的多态,不是属性的多态(多态与属性无关)。
2. 多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象。
3. 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。
*/
class Animal {
public void shout() {
System.out.println("叫了一声!");
}
}
class Dog extends Animal {
public void shout() {
System.out.println("旺旺旺!");
}
public void seeDoor() {
System.out.println("看门中....");
}
}
class Cat extends Animal {
public void shout() {
System.out.println("喵喵喵喵!");
}
}
public class TestPolym {
public static void main(String[] args) {
Animal a1 = new Cat(); // Cat继承了Animal 向上可以自动转型
//传的具体是哪一个类就调用哪一个类的方法。大大提高了程序的可扩展性。
animalCry(a1);
Animal a2 = new Dog();//将子类对象给与了父类引用
animalCry(a2);//a2为编译类型,Dog对象才是运行时类型。
//编写程序时,如果想调用运行时类型的方法,只能进行强制类型转换。
// 否则通不过编译器的检查。
Dog dog = (Dog)a2;//向下需要强制类型转换 将转成Animal的a2转回Dog
dog.seeDoor();
}
// 有了多态,只需要让增加的这个类继承Animal类就可以了。
static void animalCry(Animal a) {
a.shout();
}
/* 如果没有多态,我们这里需要写很多重载的方法。
* 每增加一种动物,就需要重载一种动物的喊叫方法。非常麻烦。
static void animalCry(Dog d) {
d.shout();
}
static void animalCry(Cat c) {
c.shout();
}*/
}
抽象方法和抽象类 abstract
//1. 有抽象方法的类只能定义成抽象类
//2. 抽象类不能实例化,即不能用new来实例化抽象类。
//3. 抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。
//4. 抽象类只能用来被继承。
//5. 抽象方法必须被子类实现。
public abstract class Animal {
//使用abstract修饰的方法,没有方法体,只有声明。
//定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。
//第一:没有实现 第二:子类必须实现
abstract public void shout();
public void run() {
System.out.println("跑啊跑");
}
public static void main(String[] args) {
// Animal a = new Animal(); 不能用new来实例化抽象类
Animal a = new Dog(); //可以new子类对象
}
}
class Dog extends Animal{
public void shout() {
//包含抽象方法的类就是抽象类。通过abstract方法定义规范,然后要求子类必须定义具体实现。
//通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
System.out.println("必须实现父类的shout");
}
}
接口 interface
public class TestInterface {
public static void main(String[] args) {
Volant volant = new Angel();//Volant 后Angel里面就只有赋值和fly方法
volant.fly();
//volant.helpOther(); 无法执行此方法
System.out.println(Volant.FLY_HIGHT);
Honest honest = new GoodMan();
honest.helpOther();
Volant fly = new BirdMan();
fly.fly();
}
}
/**飞行接口*/
interface Volant {
int FLY_HIGHT = 100; // 总是:public static final类型的;
void fly(); //总是:public abstract void fly();
}
/**善良接口*/
interface Honest {
void helpOther();
}
/**Angle类实现飞行接口和善良接口*/
class Angel implements Volant, Honest{ //实现类可以实现多个父接口
public void fly() {
System.out.println("我是天使,飞起来啦!");
}
public void helpOther() {
System.out.println("扶老奶奶过马路!");
}
}
class GoodMan implements Honest {
public void helpOther() {
System.out.println("扶老奶奶过马路!");
}
}
class BirdMan implements Volant {
public void fly() {
System.out.println("我是鸟人,正在飞!");
}
}
/*
接口可以多继承:接口C继承接口A和B
interface A {
void testa();
}
interface B {
void testb();
}
interface C extends A, B {
void testc();
}
class Test implements C {
public void testc() {
}
public void testa() {
}
public void testb() {
}
}
*/
装饰设计模式
/*
*好处:
*耦合性不强,被装饰类的变化与装饰类的变化无关
*/
public class Demo6_Wrap {
public static void main(String[] args) {
HeiMaStudent hms = new HeiMaStudent(new Student());
hms.code();
}
}
interface Coder{
public void code();
}
class Student implements Coder{
@Override
public void code() {
// TODO Auto-generated method stub
System.out.println("javase");
System.out.println("javaweb");
}
}
class HeiMaStudent implements Coder{
//1.获取被装饰类的引用
private Student s; //获取学生引用
//2.在构造方法中传入被装饰类的对象
public HeiMaStudent(Student s) {
this.s = s;
}
//对原有的功能进行升级
@Override
public void code() {
s.code();
System.out.println("数据库");
System.out.println("ssh");
System.out.println("大数据");
System.out.println("。。。");
}
}
静态内部类
public class TestStaticInnerClass {
public static void main(String[] args) {
Outer2.Inner2 inner = new Outer2.Inner2();//静态内部类
TestStaticInnerClass.test(new AA() {
public void aa() {
System.out.println("TestStaticInnerClass");
}
});
}
public static void test(AA a) {
System.out.println("调用");
a.aa();
}
}
class Outer2{
static class Inner2{
}
}
interface AA{
void aa();
}
非静态内部类
public class TestInterClass {
public static void main(String[] args) {
//创建内部类对象
Outer.Inner inner = new Outer().new Inner();
inner.outshow();
inner.show();
}
}
class Outer{
private int age = 10;
public void testOuter() {
System.out.println("Outer.testOuter()");
}
class Inner{////内部类中可以声明与外部类同名的属性与方法
//内部类可以使用public、default、protected 、private以及static修饰。
//编译完成后会出现Outer.class和Outer$Inner.class两个类的字节码文件。
public void outshow() {
System.out.println("访问外部类成员变量"+Outer.this.age);
}
//内部类中可以声明与外部类同名的属性与方法
private int age = 20;
public void show(){
System.out.println(age);//20
}
}
}
自动装箱,自动拆箱
public class TestAutoBox {
public static void main(String[] args) {
Integer a = 234;//自动装箱。Integer a = Integer.valueOf(234);
int b = a;//自动拆箱。编译器会修改成:int b = a.intValue();
Integer c = null;
if(c!=null) {
int d = c; //自动拆箱:调用了 c.intValue()
}
//缓存[-128,127]之间的数字。实际就是系统初始的时候,创建了[-128,127]之间的一个缓存数组
//当我们调用valueOf()时,首先检查是否在[-128,127]之间,如果在这个范围则直接从缓存数组中拿出已经建好的对象
//如果不在这个范围,则创建新的Integer对象
Integer in1 = -128;
Integer in2 = -128;
System.out.println(in1==in2);//true 因为-128在缓存范围内 直接取
System.out.println(in1.equals(in2));//true
Integer in3 = 1234;
Integer in4 = 1234;
System.out.println(in3==in4);//false 因为1234不在缓存范围内 new一个新的
System.out.println(in3.equals(in4));//true
}
}
包装类
- A:为什么会有基本类型包装类将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据。
- 将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据。
- B:常用操作常用的操作之一:用于基本数据类型与字符串之间的转换。
- 常用的操作之一:用于基本数据类型与字符串之间的转换。
- C:基本类型和包装类的对应byte - Byteshort - Shortint - Integerlong - Longfloat - Floatdouble - Doublechar - Characterboolean - Boolean
- byte - Byte
- short - Short
- int - Integer
- long - Long
- float - Float
- double - Double
- char - Character
- boolean - Boolean
import java.util.Arrays;
/*
* Integer类的使用,其他包装类用法类似
*/
public class TestWrappedClass {
public static void main(String[] args) {
//基本数据类型转成包装类对象
Integer a = new Integer(3);
Integer b = Integer.valueOf(30);
//把包装类对象转成基本数据类型
int c = b.intValue();
double d = b.doubleValue();
//把字符串转成包装类对象
Integer e = new Integer("999");
Integer f = Integer.parseInt("999888");
//把包装类对象转成字符串
String str = f.toString();
//常见的常量
System.out.println("int类型最大的整数:"+Integer.MAX_VALUE);
}
}
BigInteger
/*
BigInteger的概述
可以让超过Integer范围内的数据进行运算
*/
import java.math.BigInteger;
public class Demo4_BigInteger {
public static void main(String[] args) {
//long num = 123456789098765432123L;
//String s = "123456789098765432123";
BigInteger bi1 = new BigInteger("100");
BigInteger bi2 = new BigInteger("2");
System.out.println(bi1.add(bi2));//+
System.out.println(bi1.subtract(bi2));//-
System.out.println(bi1.multiply(bi2));//*
System.out.println(bi1.divide(bi2));//(除)
BigInteger[] arr = bi1.divideAndRemainder(bi2);//取除数和余数
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
import java.math.BigInteger;
/*
*1000的阶乘结果所有零和尾部零的个数
*1000的阶乘结果尾部零的个数
*/
public class Test6 {
public static void main(String[] args) {
//demo1();
demo2();
}
private static void demo2() {//1000的阶乘结果尾部零的个数
BigInteger bi1 = new BigInteger("1");
for(int i=1;i<=1000;i++) {
BigInteger bi2 = new BigInteger(i+"");
bi1=bi1.multiply(bi2);//将bi1与bi2相乘的结果赋值给bi1
}
String str = bi1.toString();//获取字符串表现形式
StringBuilder sb = new StringBuilder(str);
str = sb.reverse().toString();//链式编程 反转原本字符
int count = 0;
for(int i=0;i<str.length();i++) {
if('0'!=str.charAt(i)) {
break;
}else {
count++;
}
}
System.out.println(count);
}
private static void demo1() {//求1000的阶乘中所有的零
int result = 1;
for(int i=1;i<=1000;i++) {
result = result*i;
}
System.out.println(result);//因为1000的阶乘远远超出int的取值范围
BigInteger bi1 = new BigInteger("1");
for(int i=1;i<=1000;i++) {
BigInteger bi2 = new BigInteger(i+"");
bi1=bi1.multiply(bi2);//将bi1与bi2相乘的结果赋值给bi1
}
System.out.println(bi1);
String str = bi1.toString();//获取字符串表现形式
int count=0;
for(int i=0;i<str.length();i++) {
if('0'==str.charAt(i)) {//如果出现0字符
count++;//计数器加一
}
}
System.out.println(count);
}
}
BigDecimal
import java.math.BigDecimal;
public class Demo5_BigDecimal {
/**
BigDecimal的概述
* 由于在运算的时候,float类型和double很容易丢失精度,演示案例。
* 所以,为了能精确的表示、计算浮点数,Java提供了BigDecimal
* 不可变的、任意精度的有符号十进制数。
*/
public static void main(String[] args) {
System.out.println(2.0 - 1.1);
BigDecimal bd1 = new BigDecimal(2.0);//这种方式在开发中不推荐,因为不够精确
BigDecimal bd2 = new BigDecimal(1.1);
System.out.println(bd1.subtract(bd2));
BigDecimal bd1 = new BigDecimal("2.0");//通过构造中传入字符串的方式,开发时推荐
BigDecimal bd2 = new BigDecimal("1.1");
System.out.println(bd1.subtract(bd2));
BigDecimal bd1 = BigDecimal.valueOf(2.0);//这种方式在开发中也是推荐的
BigDecimal bd2 = BigDecimal.valueOf(1.1);
System.out.println(bd1.subtract(bd2));
}
}
Math操作与Random随机数生成
import java.util.Random;
public class TestMath {
public static void main(String[] args) {
//取整相关操作
System.out.println(Math.ceil(3.2));//大于a的最小整数
System.out.println(Math.floor(3.2));//小于a的最大整数
System.out.println(Math.round(3.2));
System.out.println(Math.round(3.8));
//绝对值、开方、a的b次幂等操作
System.out.println(Math.abs(-45));
System.out.println(Math.sqrt(64));
System.out.println(Math.pow(5, 2));
System.out.println(Math.pow(2, 5));
//Math类中常用的常量
System.out.println(Math.PI);
System.out.println(Math.E);
//随机数
System.out.println(Math.random());// [0,1)
System.out.println("-----------分割----------------");
Random rand = new Random();
//随机生成[0,1)之间的double类型的数据
System.out.println(rand.nextDouble());
//随机生成int类型允许范围之内的整型数据
System.out.println(rand.nextInt());
//随机生成[0,1)之间的float类型的数据
System.out.println(rand.nextFloat());
//随机生成false或者true
System.out.println(rand.nextBoolean());
//随机生成[0,10)之间的int类型的数据
System.out.print(rand.nextInt(10));
//随机生成[20,30)之间的int类型的数据
System.out.print(20 + rand.nextInt(10));
//随机生成[20,30)之间的int类型的数据(此种方法计算较为复杂)
System.out.print(20 + (int) (rand.nextDouble() * 10));
}
}
Date类与Calendar日期类
Date类的常见用法 时间对象和字符串之间的相互转换
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
* DateFormat抽象类和SimpleDateFormat实现类的使用
*/
public class TestDate {
public static void main(String[] args) throws ParseException {
Date d = new Date();
System.out.println(d);//Sun Aug 02 11:52:05 CST 2020(因当前时间不同具有差异)
Date e = new Date(2000);//1970-1-1 增加 2s 时区不同增加8时
System.out.println(e);//Thu Jan 01 08:00:02 CST 1970
System.out.println(d.getTime());//获得毫秒数
System.out.println(d.after(e));//测试此日期是否在指定日期之后 true
//以后遇见日期处理:使用Canlendar日期类
Date f = new Date(2020-1900,7-1,18);//已被废弃但可用 2020-7-18
System.out.println(f);//获得毫秒数
//把时间对象按照"格式字符串指定的格式"转成相应的字符串
DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String str = df.format(new Date());
System.out.println(str);//按格式输出 2020-08-02 11:52:05
DateFormat de = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
String str2 = de.format(new Date());
System.out.println(str2);//按格式输出 2020年08月02日 11:52:05
//把字符串按照"格式字符串指定的格式"转成相应的时间对象
DateFormat dg = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分ss秒");
Date date = dg.parse("2020年7月18日 13时10分0秒");//选择了抛出异常
System.out.println(date);//按格式输出:Sat Jul 18 13:10:00 CST 2020
//测试其他的格式字符 例如:利用D,获得本事件对象所处年数的多少天
DateFormat dh = new SimpleDateFormat("D");
String str3 = dh.format(new Date());
System.out.println(str3);//输出今天位于年中的天数 215(因当前时间不同具有差异)
}
}
Calendar日期类的使用
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class TestCanlender {
public static void main(String[] args){
Calendar calendar = new GregorianCalendar(2999, 10, 9, 22, 10, 50);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DATE);//也可使用:DAY_OF_MONTH
int weekday = calendar.get(Calendar.DAY_OF_WEEK);//星期几
System.out.println(year);
System.out.println(month);//0-11 0是1月
System.out.println(day);
System.out.println(weekday);//1-7 1代表星期日
//设置日期的相关元素
Calendar c2 = new GregorianCalendar();
c2.set(Calendar.YEAR, 8012);//设置年
System.out.println(c2);
//日期的计算
Calendar c3 = new GregorianCalendar();
c3.add(Calendar.DATE, -100);//往前一百天
System.out.println(c3);
//日期对象和时间对象的转化
Date d4 = c3.getTime();
Calendar c4 = new GregorianCalendar();
c4.setTime(new Date());
printCalendar(c4);
}
public static void printCalendar(Calendar c) {
//打印:1918年10月10日 11:23:45 周三
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;//0-11
int date = c.get(Calendar.DAY_OF_MONTH);
int dayweek = c.get(Calendar.DAY_OF_WEEK)-1;//0周日...
String dayweek2 = dayweek == 0?"日":dayweek+"";
int hour = c.get(Calendar.HOUR);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
System.out.println(year+"年"+month+"月"+date+"日"+hour+"时"+minute+"分"+second+"秒"+
" 周"+dayweek2);
}
}
可视化日历程序
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Scanner;
public class TestCalendar2 {
public static void main(String[] args) throws ParseException{
System.out.println("请输入日期(格式:2020-7-18):");
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();//"2020-2-18"
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date date = df.parse(str);
Calendar c = new GregorianCalendar();
c.setTime(date);
int day = c.get(Calendar.DAY_OF_MONTH);//获取今天的在月份中的天数
int days= c.getActualMaximum(Calendar.DATE);//c.getActualMaximum(Calendar.DATE)获取当月最大天数
System.out.println("日\t一\t二\t三\t四\t五\t六");
c.set(Calendar.DAY_OF_MONTH, 1);//设置一个月的第几天
for(int i =0;i<c.get(Calendar.DAY_OF_WEEK)-1;i++){//排序最开始的空格
System.out.print("\t");
}
for(int i=1;i<=days;i++) {
if(day==c.get(Calendar.DAY_OF_MONTH)) {
System.out.print(c.get(Calendar.DAY_OF_MONTH)+"*\t");
}
else {
System.out.print(c.get(Calendar.DAY_OF_MONTH)+"\t");
}
if(c.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY) {//判断是否为周六
System.out.println();//换行
}
c.add(Calendar.DAY_OF_MONTH, 1);//天数加1
}
}
}
/*
请输入日期(格式:2020-7-18):
2020-7-18
日 一 二 三 四 五 六
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18*
19 20 21 22 23 24 25
26 27 28 29 30 31
*/
字符串
- 1.使用String类的场景:在字符串不经常变化的场景中可以使用String类,例如常量的声明、少量的变量运算。
- 2.使用StringBuffer类的场景:在频繁进行字符串运算(如拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用StringBuffer,例如XML解析、HTTP参数解析和封装。
- 3.使用StringBuilder类的场景:在频繁进行字符串运算(如拼接、替换、和删除等),并且运行在单线程的环境中,则可以考虑使用StringBuilder,如SQL语句的拼装、JSON封装等。
字符串类的基本用法
public class TestString {
public static void main(String[] args) {
String str = "abc";
String str2 = new String("abc");
String str3 = "Hello" + 22;
System.out.println(str3);
String str4 = "abc";
System.out.println(str==str4);
System.out.println(str==str2);//str和str2不是同一个对象
//因此通常比较字符串,使用equals
System.out.println(str.equals(str2));
System.out.println(str.charAt(2));//提取下标为3的字符
System.out.println(str.length());//字符串的长度
System.out.println(str.equals(str2));//比较两个字符串是否相等
String str5 = new String("Abc");
System.out.println(str.equalsIgnoreCase(str5));//比较两个字符串(忽略大小写)
System.out.println(str.indexOf("Java"));//字符串str中是否包含Java
System.out.println(str.indexOf("b"));//字符串str中是否包含b
String s = str.replace('a', '&');//将s1中的空格替换成&
System.out.println("result is :" + s);
System.out.println(str5.toLowerCase());//转小写
System.out.println(str.toUpperCase());//转大写
System.out.println(str.startsWith("a"));//是否以a开头
System.out.println(str.endsWith("c"));//是否以c开头
System.out.println(str.substring(1));//提取字符串:从下标为1的开始到字符串结尾为止
System.out.println(str.substring(1,2));//提取字符串:下标[1,2),不含2
System.out.println(str.trim());//去除字符串首尾空格,注:中间的空格不能去除
}
}
字符串的注意事项
public class TestString {
public static void main(String[] args) {
String st = "aaabbbb";
String st2 = st.substring(2,5);
System.out.println(st);//aaabbbb
System.out.println(st2);//abb
//编译器做了优化,直接在编译的时候将字符串进行拼接
String str1 = "hello" + " java";
String str2 = "hello java";
System.out.println(str1 == str2);//true
String str3 = "hello";
String str4 = " java";
//编译时不知变量中存储的是什么,所以没办法在编译时优化
String str5 = str3 + str4;
System.out.println(str2 == str5);//false
System.out.println(str2.equals(str5));//true
}
}
StringBuilder、StringBuffer
//StringBuilder线程不安全,效率高(一般使用它);StringBuffer线程安全,效率低
public class TestStringBuilder {
public static void main(String[] args) {
String str;
StringBuilder sb = new StringBuilder("abcdefg");
System.out.println(Integer.toHexString(sb.hashCode()));//7a79be86
System.out.println(sb);//abcdefg
sb.setCharAt(2, 'M');
System.out.println(Integer.toHexString(sb.hashCode()));//7a79be86
System.out.println(sb);//abMdefg
}
}
StringBuilder、StringBuffer可变字符序列的常用方法
public class TestStringBuilder2 {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for(int i = 0;i<26;i++) {
char temp = (char)('a'+i);
sb.append(temp);
}
System.out.println(sb);//abcdefghijklmnopqrstuvwxyz
sb.reverse();//倒序
System.out.println(sb);//zyxwvutsrqponmlkjihgfedcba
sb.setCharAt(3, '程');//更改
System.out.println(sb);//zyx程vutsrqponmlkjihgfedcba
sb.insert(0, "我");//插入
System.out.println(sb);//我zyx程vutsrqponmlkjihgfedcba
sb.delete(20, 23);
System.out.println(sb);//我zyx程vutsrqponmlkjihdcba
//链式调用
sb.insert(0, '我').insert(1, '爱').insert(2, '你');
System.out.println(sb);//我爱你我zyx程vutsrqponmlkjihdcba
}
}
StringBuilder、StringBuffer可变字符序列和不可变字符序列使用的陷阱
public class TestStringBuilder3 {
public static void main(String[] args) {
/**使用String进行字符串的拼接*/
String str8 = "";
//本质上使用StringBuilder拼接, 但是每次循环都会生成一个StringBuilder对象
long num1 = Runtime.getRuntime().freeMemory();//获取系统剩余内存空间
long time1 = System.currentTimeMillis();//获取系统的当前时间
for (int i = 0; i < 5000; i++) {
str8 = str8 + i;// i 与连接 各位一个对象 相当于产生了10000个对象
}
long num2 = Runtime.getRuntime().freeMemory();
long time2 = System.currentTimeMillis();
System.out.println("String占用内存 : " + (num1 - num2));//String占用内存 : 15474856
System.out.println("String占用时间 : " + (time2 - time1));//String占用时间 : 53
/**使用StringBuilder进行字符串的拼接*/
StringBuilder sb1 = new StringBuilder("");
long num3 = Runtime.getRuntime().freeMemory();
long time3 = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
sb1.append(i);//此方法不需要重复的生产对象
}
long num4 = Runtime.getRuntime().freeMemory();
long time4 = System.currentTimeMillis();
System.out.println("StringBuilder占用内存 : " + (num3 - num4));//StringBuilder占用内存 : 1321144
System.out.println("StringBuilder占用时间 : " + (time4 - time3));//StringBuilder占用时间 : 0
}
}
数组
public class Test01 {
public static void main(String[] args) {
int[] a= {2,3,4,5};//静态初始化
int[] arr01 = new int[10];//[]可在前也可在后 且必须给数组分配空间(指长度)
String arr02[] = new String[5] ;
for(int i=0;i<arr01.length;i++) {
arr01[i] = i;
}
for(int i=0;i<arr01.length;i++) {
System.out.println(arr01[i]);
}
for(int m:a) {//foreach循环:用于读取数组元素的值,不能修改元素的值
System.out.println(m);
}
//赋值方法1 (动态初始化)
User[] arr03 = new User[3];
arr03[0] = new User(1001,"yj");
arr03[1] = new User(1002,"yj");
arr03[2] = new User(1003,"yj");
//赋值方法2
User[] b = {new User(1001,"yj"),new User(1002,"yj"),new User(1003,"yj")};
for(int i=0;i<arr03.length;i++) {
System.out.println(arr03[i].getName());
}
//数组默认初始化
int a2[] = new int[2];//默认:0,0
boolean[] b = new boolean[2];//默认值:false,false
String[] s = new String[2];//默认值:null,null
}
}
class User{
private int id;
private String name;
public User(int id,String name) {
this.id=id;
this.name=name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id=id;
}
public String getName() {
return name;
}
public void setName(int id) {
this.name=name;
}
}
数组拷贝、删除、扩容
public class TestArrayCopy {
public static void main(String[] args) {
String[] s1 = {"aa","bb","cc","dd","ee"};
String[] s2 = new String[10];
System.arraycopy(s1, 2, s2, 6, 3);//(被拷贝者,拷贝开始下标,被拷到,被拷到开始下标,拷贝长度)
for(int i=0;i<s2.length;i++) {
System.out.println(i+"--"+s2[i]);
}
String[] s3 = {"阿里","京东","百度","腾讯","谷歌"};
removeElement(s3,2);
extendRange();
}
//测试从数组中删除某个元素(本质上还是数组的拷贝)
public static String[] removeElement(String[] s,int index) {
System.arraycopy(s, index+1, s, index, s.length-index-1);
s[s.length-1] = null;
for(int i=0;i<s.length;i++) {
System.out.println(i+"--"+s[i]);
}
return s;
}
//数组的扩容(本质上:先定义一个更大的数组,然后将原数组内容原封不动拷贝到新数据中)
public static void extendRange() {
String[] s1 = {"aa","bb","cc"};
String[] s2 = new String[s1.length+10];
System.arraycopy(s1, 0, s2, 0, s1.length);
for(String temp:s2) {
System.out.println(temp);
}
}
}
java.util.Arrays工具类的使用
import java.util.Arrays;
public class TestArrays {
public static void main(String[] args) {
int[] a = {100,20,30,5,150,80,200};
System.out.println(a);
System.out.println(Arrays.toString(a));//转换
Arrays.sort(a);
System.out.println(Arrays.toString(a));//排序
System.out.println(Arrays.binarySearch(a, 30));//搜索30的下标
}
}
二维数组
public class Test2DimensionArray {
public static void main(String[] args) {
int[][] b = new int[3][];//二维数组
b[0] = new int[]{20,30};//二维数组赋值
b[1] = new int[]{10,15,80};
b[2] = new int[]{50,60};
System.out.println(b[1][2]);
int[][] a = {
{20,30},
{10,15,80},
{50,60}
};
System.out.println(a[2][1]);
}
}
测试数组存储表格数据
import java.util.Arrays;
public class TestArrayTableData {
public static void main(String[] args) {
Object[] emp1 = {1001,"yj",18,"前端",22};
Object[] emp2 = {1002,"yj",18,"web",22};
Object[] emp3 = {1003,"yj",18,"全栈",22};
Object[][] tableData = new Object[3][];
tableData[0] = emp1;
tableData[1] = emp2;
tableData[2] = emp3;
for(Object[] temp:tableData) {
System.out.println(Arrays.toString(temp));
}
}
}
/*
[1001, yj, 18, 前端, 22]
[1002, yj, 18, web, 22]
[1003, yj, 18, 全栈, 22]
*/
二分法查找
import java.util.Arrays;
public class TestBinarySearch {
public static void main(String[] args) {
int[] arr = {30,10,60,20,90,0,70,40,50,80};
Arrays.sort(arr);
int value = 10;//要查找的值
System.out.println(Arrays.toString(arr));//[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
System.out.println(myBinarySearch(arr,value));//1
}
public static int myBinarySearch(int[] arr,int value) {
int low = 0;
int high = arr.length-1;
while(low<=high) {
int mid = (low+high)/2;
if(value==arr[mid]) {
return mid;
}
if(value>arr[mid]) {
low=mid+1;
}
if(value<arr[mid]) {
high = mid-1;
}
}
return -1;
}
}
冒泡排序
import java.util.Arrays;
public class TestBubbleSort {
public static void main(String[] args) {
int[] values = {3,1,6,2,9,0,7,4,5,8};
int temp = 0;
for(int i=0;i<values.length-1;i++) {
boolean flag = true;
for(int j = 0;j<values.length-i-1;j++) {
//比较大小,换顺序
if(values[j]>values[j+1]) {
temp = values[j];
values[j] = values[j+1];
values[j+1] = temp;
flag = false;
}
System.out.println(Arrays.toString(values));
}
if(flag) {//当循环一遍未发生交换时 结束程序
System.out.println("#####----结束----####");
break;
}
System.out.println("#####----分隔符----####");
}
}
}
正则表达式 Regex
- A:正则表达式是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串。其实就是一种规则。有自己特殊的应用。作用:比如注册邮箱,邮箱有用户名和密码,一般会对其限制长度,这个限制长度的事情就是正则表达式做的
- 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串。其实就是一种规则。有自己特殊的应用。
- 作用:比如注册邮箱,邮箱有用户名和密码,一般会对其限制长度,这个限制长度的事情就是正则表达式做的
- B:案例演示需求:校验qq号码.1:要求必须是5-15位数字2:0不能开头3:必须都是数字a:非正则表达式实现b:正则表达式实现
- 需求:校验qq号码.1:要求必须是5-15位数字2:0不能开头3:必须都是数字
- 1:要求必须是5-15位数字
- 2:0不能开头
- 3:必须都是数字
- a:非正则表达式实现
- b:正则表达式实现
- 具体正则方法请参考本博客正则篇
public class Demo1_Regex {
public static void main(String[] args) {
System.out.println(checkQQ("012345"));
System.out.println(checkQQ("a1b345"));
System.out.println(checkQQ("123456"));
System.out.println(checkQQ("1234567890987654321"));
String regex = "[1-9]\\d{4,14}";
System.out.println("2553868".matches(regex));//true
System.out.println("012345".matches(regex));//false
System.out.println("2553868abc".matches(regex));//fasle
}
/*
* 需求:校验qq号码.
* 1:要求必须是5-15位数字
* 2:0不能开头
* 3:必须都是数字
* 校验qq
* 1,明确返回值类型boolean
* 2,明确参数列表String qq
*/
public static boolean checkQQ(String qq) {
boolean flag = true;//如果校验qq不符合要求就把flag置为false,如果符合要求直接返回
if(qq.length() >= 5 && qq.length() <= 15) {
if(!qq.startsWith("0")) {
char[] arr = qq.toCharArray();//将字符串转换成字符数组
for (int i = 0; i < arr.length; i++) {
char ch = arr[i];//记录每一个字符
if(!(ch >= '0' && ch <= '9')) {
flag = false;//不是数字
break;
}
}
}else {
flag = false;//以0开头,不符合qq标准
}
}else {
flag = false;//长度不符合
}
return flag;
}
}
Matcher与Pattern
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo2 {
public static void main(String[] args) {
demo1();
String s = "我的手机是18511866260,我曾用过18987654321,还用过18812345678";
String regex = "1[3578]\\d{9}";
Pattern p = Pattern.compile(regex);//获取到正则表达式
Matcher m = p.matcher(s);//获取匹配器
/*boolean b1 = m.find();
System.out.println(b1);
System.out.println(m.group());
boolean b2 = m.find();
System.out.println(b2);
System.out.println(m.group());*/
while(m.find())
System.out.println(m.group());//返回3个号码
}
public static void demo1() {
Pattern p = Pattern.compile("a*b");//获取到正则表达式
Matcher m = p.matcher("aaaaab");//获取匹配器
boolean b = m.matches();//看是否能匹配,匹配就返回true
System.out.println(b);//true
System.out.println("aaaaab".matches("a*b"));//true
}
}
泛型与Collection、Map
泛型
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/*
我们可以在类的声明处增加泛型列表,如:<T,E,V>。
此处,字符可以是任何标识符,一般采用这3个字母。
*/
public class TestGenerics {
public static void main(String[] args) {
// 这里的”String”就是实际传入的数据类型;
MyCollection<String> mc = new MyCollection<String>();
mc.set("aaa", 0);
mc.set("bbb", 1);
String str = mc.get(1); //加了泛型,直接返回String类型,不用强制转换;
System.out.println(str);
/*
* 以下代码中List、Set、Map、Iterator都是与容器相关的接口;
* List<String> list = new ArrayList<String>();
* Set<String> mans = new HashSet<String>();
* Map<Integer, Man> maps = new HashMap<Integer, Man>();
* Iterator<Man> iterator = mans.iterator();
*/
}
}
class MyCollection<E> {// E:表示泛型;(形参)
Object[] objs = new Object[5];
public void set(E e, int index) {// E:表示泛型;
objs[index] = e;
}
public E get(int index) {// E:表示泛型;
return (E) objs[index];
}
}
Collection
Collection中有List Set两个接口
- List有序可重复List集合中含有 ArrayList LinkedList VectorArrayList底层是用数组实现的存储。特点:
查询修改效率高,增删效率低,线程不安全
一般使用他。数组长度是有限的,而ArrayList是可以存放任意数量的对象,长度不受限制,那么它是怎么实现的呢?本质上就是通过定义新的更大的数组,将旧数组中的内容拷贝到新数组,来实现扩容。 ArrayList的Object数组初始化长度为10,如果我们存储满了这个数组,需要存储第11个对象,就会定义新的长度更大的数组,并将原数组内容和新的元素一起加入到新数组中LinkedList底层是用链表实现,特点:增删效率高,查询修改效率低,线程不安全
Vector底层数组实现,特点:线程安全,增删改查效率低
- List集合中含有 ArrayList LinkedList VectorArrayList底层是用数组实现的存储。特点:
查询修改效率高,增删效率低,线程不安全
一般使用他。数组长度是有限的,而ArrayList是可以存放任意数量的对象,长度不受限制,那么它是怎么实现的呢?本质上就是通过定义新的更大的数组,将旧数组中的内容拷贝到新数组,来实现扩容。 ArrayList的Object数组初始化长度为10,如果我们存储满了这个数组,需要存储第11个对象,就会定义新的长度更大的数组,并将原数组内容和新的元素一起加入到新数组中LinkedList底层是用链表实现,特点:增删效率高,查询修改效率低,线程不安全
Vector底层数组实现,特点:线程安全,增删改查效率低
- ArrayList底层是用数组实现的存储。特点:
查询修改效率高,增删效率低,线程不安全
一般使用他。 - 数组长度是有限的,而ArrayList是可以存放任意数量的对象,长度不受限制,那么它是怎么实现的呢?
- 本质上就是通过定义新的更大的数组,将旧数组中的内容拷贝到新数组,来实现扩容。 ArrayList的Object数组初始化长度为10,如果我们存储满了这个数组,需要存储第11个对象,就会定义新的长度更大的数组,并将原数组内容和新的元素一起加入到新数组中
- LinkedList底层是用链表实现,特点:
增删效率高,查询修改效率低,线程不安全
- Vector底层数组实现,特点:
线程安全,增删改查效率低
- Set无序不重复Set集合中含有 HashSet TreeSet
- Set集合中含有 HashSet TreeSet
Collections辅助类的使用
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
/*
* 可以通过此工具类实现Collection、Map、List、Set、Queue等集合接口的数据操作
*/
public class TestCollections {
public static void main(String[] args) {
List<String> all = new ArrayList<>();
Collections.addAll(all, "Hellow","YJ","jsfan");//保存数据
System.out.println(all);//输出集合内容
Collections.reverse(all);//集合反序
System.out.println(all);//输出集合内容
System.out.println(Collections.binarySearch(all, "YJ"));//二分查找
Collections.shuffle(all);//集合随机排序
System.out.println(all);//输出集合内容
}
}
测试Collection接口中的方法
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class TestList {
public static void main(String[] args) {
test01();
test02();
test03();
}
public static void test01() {
Collection<String> c = new ArrayList<String>();
System.out.println(c.size());//0
System.out.println(c.isEmpty());//true
c.add("yj大哥");//因定义泛型 所以需为字符串
c.add("yj二哥");
System.out.println(c);//[yj大哥, yj二哥]
System.out.println(c.size());//2
System.out.println(c.contains("yj大哥"));//是否包含 true
Object[] objs = c.toArray();//转出
System.out.println(objs[0]+ " " +objs[1]);//yj大哥 yj二哥
c.remove("yj二哥");//移除
System.out.println(c);//[yj大哥]
c.clear();//清空
System.out.println(c.size());//0
}
public static void test02() {
List<String> list01 = new ArrayList<>();//可省略 List可替换为Collection
list01.add("aa");
list01.add("bb");
list01.add("cc");
List<String> list02 = new ArrayList<>();//可省略 List可替换为Collection
list02.add("aa");
list02.add("dd");
list02.add("ee");
System.out.println("list01:"+list01);//list01:[aa, bb, cc]
// list01.addAll(list02);//合并
// list01.removeAll(list02);//删除list01与list02相同部分 显示list01
list01.retainAll(list02);//显示相同部分
System.out.println("list01:"+list01);//list01:[aa]
System.out.println(list01.contains(list02));//list02中是否有list01所有元素 false
}
public static void test03() {
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
System.out.println(list);//[A, B, C, D]
list.add(2,"插入");//在第三个元素前插入
System.out.println(list);//[A, B, 插入, C, D]
list.remove(2);//移除
System.out.println(list);//[A, B, C, D]
list.set(2, "老二");//第三个元素替换
System.out.println(list);//[A, B, 老二, D]
System.out.println(list.get(2));//获取第三个元素 老二
list.add("C");
list.add("B");
list.add("A");
System.out.println(list.indexOf("B"));//寻找元素所在位置 1 未找到则返回-1
System.out.println(list.lastIndexOf("B"));//反向寻找元素所在位置 5
}
}
Vector
import java.util.List;
import java.util.Vector;
public class TestVector {
public static void main(String[] args) {
List<String> a = new Vector<>();//实例化集合接口
a.add("aaa");
System.out.println(a);
...
}
}
表格数据的存储
范例1:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/*
* 测试表格数据的存储
* ID 姓名 年龄 薪水 入职日期
* 1001 yj 22 10000 2020.11.11
* 1002 jsfan 1 8000 2020.2.1
* 1003 react 2 6000 2019.1.1
* 1004 vue 2 6000 2019.11.11
* 1005 Java 0 2000 2020.7.23
* 每一行数据使用一个:Map(也可使用其他容器)
* 整个表格使用一个List(也可使用其他容器)
* ORM思想:对象关系映射
*/
public class TestStoreData {
public static void main(String[] args) {
Map<String,Object> row1 = new HashMap<>();
row1.put("id", 1001);
row1.put("姓名", "yj");
row1.put("年龄", 22);
row1.put("薪水", 10000);
row1.put("入职日期", "2020.11.11");
Map<String,Object> row2 = new HashMap<>();
row2.put("id", 1002);
row2.put("姓名", "jsfan");
row2.put("年龄", 1);
row2.put("薪水", 8000);
row2.put("入职日期", "2020.2.1");
Map<String,Object> row3 = new HashMap<>();
row3.put("id", 1003);
row3.put("姓名", "react");
row3.put("年龄", 2);
row3.put("薪水", 6000);
row3.put("入职日期", "2019.1.1");
Map<String,Object> row4 = new HashMap<>();
row4.put("id", 1004);
row4.put("姓名", "vue");
row4.put("年龄", 2);
row4.put("薪水", 6000);
row4.put("入职日期", "2019.11.11");
Map<String,Object> row5 = new HashMap<>();
row5.put("id", 1005);
row5.put("姓名", "Java");
row5.put("年龄", 0);
row5.put("薪水", 2000);
row5.put("入职日期", "2020.7.23");
List<Map<String,Object>> table1 = new ArrayList<>();
table1.add(row1);
table1.add(row2);
table1.add(row3);
table1.add(row4);
table1.add(row5);
System.out.println(table1);
for(Map<String,Object> row:table1) {
Set<String> keyset = row.keySet();//获取key值集合 [姓名, 薪水, id, 年龄, 入职日期]
for(String key:keyset) {
System.out.print(key+":"+row.get(key)+"\t");
}
System.out.println();
}
}
}
范例2:
import java.util.ArrayList;
import java.util.List;
/*
* 每一行数据使用一个:javabean对象 多行使用放到map或list中
* 整个表格使用一个Map/List
*/
public class TestStoreData02 {
public static void main(String[] args) {
User user1 = new User(1001,"yj",22,10000,"2020.11.11");
User user2 = new User(1002,"jsfan",1,8000,"2020.2.1");
User user3 = new User(1003,"react",2,6000,"2019.1.1");
User user4 = new User(1004,"vue",2,6000,"2019.11.11");
User user5 = new User(1005,"Java",0,2000,"2020.7.23");
List<User> list = new ArrayList<>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
list.add(user5);
for(User u:list) {
System.out.println(u);
}
}
}
class User{
private int id;
private String name;
private int age;
private double salary;
private String hiredate;
//一个完整的javabean。要有set和get方法,以及一个无参构造器!
public User() {
}
public User(int id, String name, int age, double salary, String hiredate) {
super();
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
this.hiredate = hiredate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(short age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getHiredate() {
return hiredate;
}
public void setHiredate(String hiredate) {
this.hiredate = hiredate;
}
@Override
public String toString() {
return "id:"+id+",name:"+name+",age:"+age+",salary:"+salary+",hiredate:"+hiredate;
}
}
HashSet与TreeSet
import java.util.HashSet;
import java.util.Set;
/*
* 测试HashSet的基本用法
* HashSet底层是哈希算法实现
* LinkedHashSet底层是链表实现,但是也可以保证元素唯一,和HashSet原理一样
* TreeSet底层是二叉树算法实现
* 一般在开发的时候不需要对存储的元素排序,且HashSet效率较高,所以在开发的时候大多用HashSet
* TreeSet通常出现在面试中,例如问有几种排序方式,和几种排序方式的区别
* 集合数据不需要保存重复的内容
*/
public class TestHashSet {
public static void main(String[] args) {
Set<String> set1 = new HashSet<>();
set1.add("aa");
set1.add("bb");
set1.add("aa");
System.out.println(set1);
set1.remove("bb");
System.out.print(set1);
//...
}
}
import java.util.Set;
import java.util.TreeSet;
/*
* 测试TreeSet的使用
* 熟悉Comparable接口(可以参考TreeMap那一节课)
*/
public class TestTreeSet {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<>();
set.add(300);
set.add(200);
set.add(600);
//按照元素递增方式排序
for(Integer m:set) {
System.out.println(m);
}
Set<Emp2> set2 = new TreeSet<>();
set2.add(new Emp2(100,"张三",3000));
set2.add(new Emp2(50,"李四",2000));
set2.add(new Emp2(150,"王五",8000));
set2.add(new Emp2(30,"赵六",20000));
//按照制定的规则排序
for(Emp2 m:set2) {
System.out.println(m);
}
}
}
class Emp2 implements Comparable<Emp2>{
int id;
String name;
double salary;
public Emp2(int id, String name, double salary) {
super();
this.id = id;
this.name = name;
this.salary = salary;
}
@Override
public int compareTo(Emp2 o) {//负数:小于, 0:等于, 正数:大于
//比较排序规则
if(this.salary>o.salary) {
return 1;
}
else if(this.salary<o.salary) {
return -1;
}
else {
if(this.id>o.id) {
return 1;
}else if(this.id<o.id) {
return -1;
}else {
return 0;
}
}
}
@Override
public String toString(){
return "id:"+id+",name"+name+",salary"+salary;
}
}
Map(HashMap与TreeMap)
import java.util.HashMap;
import java.util.Map;
/*
* 测试HashMap的使用
* Map目的是用于查找
* HashMap底层是哈希算法,针对键
* LinkedHashMap底层是链表,针对键
* TreeMap底层是二叉树算法,针对键
* 开发中用HashMap比较多
*/
public class TestMap {
public static void main(String[] args) {
Map<Integer,String> m1 = new HashMap<>();
m1.put(1,"one");//key值不能重复 如果重复则产生覆盖
m1.put(2, "two");
m1.put(3, "three");
System.out.println(m1.size());//3
System.out.println(m1.get(1));//one
System.out.println(m1.containsKey(2));//true
System.out.println(m1.containsValue("one"));//true
Map<Integer,String> m2 = new HashMap<>();
m2.put(4, "四");
m2.put(5, "五");
map.remove(4);//根据键删除元素,返回键对应的值
m1.putAll(m2);
System.out.println(m1);//{1=one, 2=two, 3=three, 4=四, 5=五}
}
}
import java.util.HashMap;
import java.util.Map;
/*
* 测试HashMap的常用方法
* HashMap线程不安全,效率高且允许key或value为null
* HashTable线程安全,效率低且不允许key或value为null
*/
public class TestMap2 {
public static void main(String[] args) {
Employee e1 = new Employee(1001,"yj",12000);
Employee e2 = new Employee(1002,"cy",5000);
Employee e3 = new Employee(1003,"cj",8000);
Map<Integer,Employee> map = new HashMap<>();
map.put(1001, e1);
map.put(1002, e2);
map.put(1003, e3);
Employee emp = map.get(1001);
System.out.println(emp);
}
}
//雇员信息
class Employee{
private int id;
private String ename;
private double salary;
public Employee(int id, String ename, double salary) {
super();
this.id = id;
this.ename = ename;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "id:"+id+" name:"+ename+" 薪水:"+salary;
}
}
import java.util.Map;
import java.util.TreeMap;
/*
* TreeMap是红黑二叉树的典型实现
* 主要用于排序
*/
public class TreeMap01 {
public static void main(String[] args) {
Map<Integer,String> treemap1 = new TreeMap<>();
treemap1.put(20, "aa");
treemap1.put(3, "bb");
treemap1.put(6, "cc");
//按照key递增的方式排序
for(Integer key:treemap1.keySet()) {
System.out.println(key+"---"+treemap1.get(key));
}
Map<Emp,String> treemap2 = new TreeMap<>();
treemap2.put(new Emp(100,"张三",5000), "张三是好小伙");
treemap2.put(new Emp(200,"李四",3000), "李是大傻子");
treemap2.put(new Emp(150,"王五",2000), "王五工作不满足");
treemap2.put(new Emp(50,"赵六",2000), "赵六真廉价");
//按照key递增的方式排序
for(Emp key:treemap2.keySet()) {
System.out.println(key+"---"+treemap2.get(key));
}
}
}
class Emp implements Comparable<Emp>{
int id;
String name;
double salary;
public Emp(int id, String name, double salary) {
super();
this.id = id;
this.name = name;
this.salary = salary;
}
@Override
public int compareTo(Emp o) {//负数:小于, 0:等于, 正数:大于
//比较排序规则
if(this.salary>o.salary) {
return 1;
}
else if(this.salary<o.salary) {
return -1;
}
else {
if(this.id>o.id) {
return 1;
}else if(this.id<o.id) {
return -1;
}else {
return 0;
}
}
}
@Override
public String toString(){
return "id:"+id+",name"+name+",salary"+salary;
}
}
迭代器Iterator遍历List、Set、Map
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class TestIterator {
public static void main(String[] args) {
testIteratorList();//使用iterator遍历List
testIteratorSet();//使用iterator遍历Set
testIteratorMap();//使用iterator遍历Map 方法1
testIteratorMap02();//方法2
}
public static void testIteratorList() {
List<String> list = new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
//使用iterator遍历List
for(Iterator<String> iter = list.iterator();iter.hasNext();) {
String temp = iter.next();
System.out.println(temp);
}
}
public static void testIteratorSet() {
Set<String> list = new HashSet<>();
list.add("aa");
list.add("bb");
list.add("cc");
//使用iterator遍历Set
for(Iterator<String> iter = list.iterator();iter.hasNext();) {
String temp = iter.next();
System.out.println(temp);
}
}
public static void testIteratorMap() {//方法1
Map<Integer,String> map = new HashMap<>();
map.put(100,"aa");
map.put(200,"bb");
map.put(300,"cc");
Set<Entry<Integer,String>> ss = map.entrySet();//<Entry<Integer,String>>当作键值对
//使用iterator遍历Map
for(Iterator<Entry<Integer,String>> iter = ss.iterator();iter.hasNext();) {
Entry<Integer,String> temp = iter.next();
System.out.println(temp.getKey()+"--"+temp.getValue());
}
}
public static void testIteratorMap02() {//方法2
Map<Integer,String> map = new HashMap<>();
map.put(100,"aa");
map.put(200,"bb");
map.put(300,"cc");
Set<Integer> KeySet = map.keySet();//获取key
//使用iterator遍历Map
for(Iterator<Integer> iter = KeySet.iterator();iter.hasNext();) {
Integer key = iter.next();
System.out.println(key+"--"+map.get(key));
}
}
}
节点与链表
节点
public class Node {
Node previous;//上一个节点
Node next;//下一个节点
Object element;//元素数据
public Node(Node previous,Node next,Object element) {
super();
this.previous = previous;
this.next = next;
this.element = element;
}
public Node(Object element) {
super();
this.element = element;
}
}
自定义链表
public class SxtLinkedList01<E> {
private Node first;//定义节点
private Node last;
private int size;
public void add(int index,E obj) {
Node newNode = new Node(obj);//接受新节点
Node temp = getNode(index);//获取需要更改的节点
if(index<0||index>size) {
throw new RuntimeException("索引数字不合法"+index);
}
if(index==size) {//针对插入节点在最后方
last=newNode;
temp.next=newNode;
newNode.previous=temp;
}
else if(temp!=null) {//针对大多情况
if(temp.previous==null) {//针对插入节点在最前方
first=newNode;
temp.previous=newNode;
newNode.next = temp;
}
else {
Node up = temp.previous;//获取需要更改的节点 在两个需更改节点中插入
up.next = newNode;//开始更改连接关系
newNode.previous = up;
newNode.next = temp;
temp.previous = newNode;
}
}
size++;
}
public void remove(int index) {
if(index<0||index>size-1) {
throw new RuntimeException("索引数字不合法"+index);
}
Node temp = getNode(index);
if(temp!=null) {
Node up = temp.previous;//将需要删除的节点断连
Node down = temp.next;
if(up!=null) {up.next=down;}//如只有一个节点
if(down!=null) {down.previous=up;}
if(index==0) {first=down;}//移除第一个节点
if(index==size-1) {last=up;}//移除最后一个节点
size--;
}
}
//[a,b,c]
public E get(int index) {
if(index<0||index>size-1) {
throw new RuntimeException("索引数字不合法"+index);
}
Node temp = getNode(index);
return temp!=null?(E)temp.element:null;
}
public Node getNode(int index) {
Node temp = null;
if(index<=(size>>1)) {
temp = first;
for(int i=0;i<index;i++) {
temp=temp.next;
}
}
else {
temp = last;
for(int i=size-1;i>index;i--) {
temp=temp.previous;
}
}
return temp;
}
public void add(E obj) {
Node node = new Node(obj);
if(first==null) {
first = node;
last = node;
}else {
node.previous = last;
node.next = null;
last.next = node;
last = node;
}
size++;
}
@Override
public String toString() {
//[a,b,c] first=a last=c
StringBuilder sb = new StringBuilder("[");
Node temp = first;
while(temp!=null) {
sb.append(temp.element+",");
temp=temp.next;
}
sb.setCharAt(sb.length()-1, ']');
return sb.toString();
}
public static void main(String[] args) {
SxtLinkedList01<String> list = new SxtLinkedList01<>();//泛型调用
list.add("a");
list.add("b");
list.add("c");
System.out.println(list);
list.add(3, "最后插入");
System.out.println(list);
list.add(1, "中间插入");
System.out.println(list);
list.add(0, "最先插入");
System.out.println(list);
System.out.println(list.get(5));
list.remove(0);
System.out.println(list);
list.remove(1);
System.out.println(list);
}
}
自定义一个ArrayList,体会其底层原理
/*
* 泛型
* 数组扩容
* 数组边界检查
* 删除
*/
public class SxtArrayList04<E> {
private Object[] elementData;
private int size;
private static final int DEFALT_CAPACITY = 10;
public SxtArrayList04() {
elementData = new Object[DEFALT_CAPACITY];
}
public SxtArrayList04(int capacity) {
if(capacity<0) {
throw new RuntimeException("索引不合法"+capacity);
}
else if(capacity==0) {
elementData = new Object[DEFALT_CAPACITY];
}
else {
elementData = new Object[capacity];
}
}
public void add(E element) {
//什么时候扩容
if(size==elementData.length) {
//怎么扩容
// 左移运算符,num << 1,相当于num乘以2 右移运算符,num >> 1,相当于num除以2
Object[] newArray = new Object[elementData.length+(elementData.length>>1)];
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
elementData = newArray;//将新数组覆盖老数组
}
elementData[size++] = element;
}
public E get(int index) {
return (E)elementData[index];
}
public void set(E element,int index) {
checkRange(index);
elementData[index] = element;
}
public void checkRange(int index) {
//索引合法判断[0,size]
if(index<0||index>size-1) {
//不合法
throw new RuntimeException("索引不合法"+index);
}
}
public void remove(E element) {
//element,将它和所有元素挨个比较,获得第一个比较为true的,返回
for(int i=0;i<size;i++) {
if(element.equals(get(i))) {
//将该元素从此处移除
remove(i);
}
}
}
public void remove(int index) {
int numMoved = size-index-1;
if(numMoved>0) {
System.arraycopy(elementData, index+1, elementData, index, numMoved);
}
elementData[--size]=null;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size==0?true:false;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i = 0;i<size;i++) {
sb.append(elementData[i]+",");
}
sb.setCharAt(sb.length()-1, ']');
return sb.toString();
}
public static void main(String[] args) {
SxtArrayList04 s1 = new SxtArrayList04();
for(int i =0;i<40;i++) {
s1.add("test"+i);
}
System.out.println(s1);
s1.set("change", 10);
System.out.println(s1.get(10));
s1.remove(3);
s1.remove("test0");
System.out.println(s1);
System.out.println(s1.size);
System.out.println(s1.isEmpty());
}
}
异常
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Test01 {
public static void main(String[] args) {
FileReader reader = null;
try {
reader = new FileReader("d:/a.txt");
char c = (char) reader.read();
System.out.println(c);
} catch (FileNotFoundException e) { //子类异常在父类异常前面
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
throws声明异常
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Test02 {
public static void main(String[] args) {
try {
readFile("joke.txt");
} catch (FileNotFoundException e) {
System.out.println("所需文件不存在!");
} catch (IOException e) {
System.out.println("文件读写错误!");
}
}
public static void readFile(String fileName) throws FileNotFoundException,IOException {
FileReader in = new FileReader(fileName);
int tem = 0;
try {
tem = in.read();
while (tem != -1) {
System.out.print((char) tem);
tem = in.read();
}
} finally {
in.close();
}
}
}
抛出异常
public class Test03 {
public static void main(String[] args) {
Person p = new Person();
p.setAge(-10);
}
}
class Person{
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if(age<0) {
throw new IllegalAgeException("年龄不能为负数");
}
this.age = age;
}
}
class IllegalAgeException extends RuntimeException{//继承Exception则需要对外抛 或try catch
public IllegalAgeException() {
}
public IllegalAgeException(String msg) {
super(msg);
}
}
原文来源: