首页 文章 精选 留言 我的

精选列表

搜索[监督学习],共10000篇文章
优秀的个人博客,低调大师

JAVA学习day13

1、finalfinal的意思为最终,不可变。final是个修饰符,它可以用来修饰类,类的成员,以及局部变量。 2、final的特点l final修饰类不可以被继承,但是可以继承其他类。class Yy {}final class Fu extends Yy{} //可以继承Yy类class Zi extends Fu{} //不能继承Fu类l final修饰的方法不可以被覆盖,但父类中没有被final修饰方法,子类覆盖后可以加final。class Fu { // final修饰的方法,不可以被覆盖,但可以继承使用 public final void method1(){} public void method2(){} }class Zi extends Fu { //重写method2方法 public final void method2(){} }l final修饰的变量称为常量,这些变量只能赋值一次。final int i = 20;i = 30; //赋值报错,final修饰的变量只能赋值一次l 引用类型的变量值为对象地址值,地址值不能更改,但是地址内的对象属性值可以修改。final Person p = new Person();Person p2 = new Person();p = p2; //final修饰的变量p,所记录的地址值不能改变p.name = "小明";//可以更改p对象中name属性值p不能为别的对象,而p对象中的name或age属性值可更改。l 修饰成员变量,需要在创建对象前赋值,否则报错。(当没有显式赋值时,多个构造方法的均需要为其赋值。)class Demo { //直接赋值 final int m = 100; //final修饰的成员变量,需要在创建对象前赋值,否则报错。 final int n; public Demo(){ //可以在创建对象时所调用的构造方法中,为变量n赋值 n = 2016; } } 3、static关键字3-1、static特点l 被static修饰的成员变量属于类,不属于这个类的某个对象。(也就是说,多个对象在访问或修改static修饰的成员变量时,其中一个对象将static成员变量值进行了修改,其他对象中的static成员变量值跟着改变,即多个对象共享同一个static成员变量)代码演示:class Demo { public static int num = 100; }class Test { public static void main(String[] args) { Demo d1 = new Demo(); Demo d2 = new Demo(); d1.num = 200; System.out.println(d1.num); //结果为200 System.out.println(d2.num); //结果为200 } }l 被static修饰的成员可以并且建议通过类名直接访问。访问静态成员的格式:类名.静态成员变量名类名.静态成员方法名(参数)对象名.静态成员变量名 ------不建议使用该方式,会出现警告对象名.静态成员方法名(参数) ------不建议使用该方式,会出现警告代码演示:class Demo { //静态成员变量 public static int num = 100; //静态方法 public static void method(){ System.out.println("静态方法"); } }class Test { public static void main(String[] args) { System.out.println(Demo.num); Demo.method(); } } 3-2、static注意事项l 静态内容是优先于对象存在,只能访问静态,不能使用this/super。静态修饰的内容存于静态区。class Demo { //成员变量 public int num = 100; //静态方法 public static void method(){ //this.num; 不能使用this/super。 System.out.println(this.num); } }l 同一个类中,静态成员只能访问静态成员class Demo { //成员变量 public int num = 100; //静态成员变量 public static int count = 200; //静态方法 public static void method(){ //System.out.println(num); 静态方法中,只能访问静态成员变量或静态成员方法 System.out.println(count); } }l main方法为静态方法仅仅为程序执行入口,它不属于任何一个对象,可以定义在任意类中。 4、定义静态常量开发中,我们想在类中定义一个静态常量,通常使用public static final修饰的变量来完成定义。此时变量名用全部大写,多个单词使用下划线连接。定义格式:public static final 数据类型 变量名 = 值;如下演示:class Company { public static final String COMPANY_NAME = "传智播客"; public static void method(){ System.out.println("一个静态方法"); } }当我们想使用类的静态成员时,不需要创建对象,直接使用类名来访问即可。System.out.println(Company.COMPANY_NAME); //打印传智播客Company.method(); // 调用一个静态方法l 注意:接口中的每个成员变量都默认使用public static final修饰。所有接口中的成员变量已是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问。interface Inter { public static final int COUNT = 100; }访问接口中的静态变量Inter.COUNT 5、匿名对象的概念匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。如:已经存在的类:public class Person{ public void eat(){ System.out.println(); }}创建一个普通对象Person p = new Person();创建一个匿名对象new Person(); 6、匿名对象的特点l 创建匿名对象直接使用,没有变量名。new Person().eat() //eat方法被一个没有名字的Person对象调用了。l 匿名对象在没有指定其引用变量时,只能使用一次。new Person().eat(); 创建一个匿名对象,调用eat方法new Person().eat(); 想再次调用eat方法,重新创建了一个匿名对象l 匿名对象可以作为方法接收的参数、方法返回值使用class Demo { public static Person getPerson(){ //普通方式 //Person p = new Person(); //return p; //匿名对象作为方法返回值 return new Person(); } public static void method(Person p){} }class Test { public static void main(String[] args) { //调用getPerson方法,得到一个Person对象 Person person = Demo.getPerson(); //调用method方法 Demo.method(person); //匿名对象作为方法接收的参数 Demo.method(new Person()); } } 7、内部类在内部类中可以直接访问外部类的所有成员; 7-1、成员内部类成员内部类,定义在外部类中的成员位置。与类中的成员变量相似,可通过外部类对象进行访问l 定义格式class 外部类 { 修饰符 class 内部类 { //其他代码 }}l 访问方式外部类名.内部类名 变量名 = new 外部类名().new 内部类名();l 成员内部类代码演示定义类class Body {//外部类,身体 private boolean life= true; //生命状态 public class Heart { //内部类,心脏 public void jump() { System.out.println("心脏噗通噗通的跳") System.out.println("生命状态" + life); //访问外部类成员变量 } }}访问内部类public static void main(String[] args) { //创建内部类对象 Body.Heart bh = new Body().new Heart(); //调用内部类中的方法 bh.jump(); } 7-2、局部内部类局部内部类,定义在外部类方法中的局部位置。与访问方法中的局部变量相似,可通过调用方法进行访问l 定义格式class 外部类 { 修饰符 返回值类型 方法名(参数) { class 内部类 { //其他代码 } }}l 访问方式在外部类方法中,创建内部类对象,进行访问l 局部内部类代码演示定义类class Party {//外部类,聚会 public void puffBall(){// 吹气球方法 class Ball {// 内部类,气球 public void puff(){ System.out.println("气球膨胀了"); } } //创建内部类对象,调用puff方法 new Ball().puff(); }}访问内部类public static void main(String[] args) { //创建外部类对象 Party p = new Party(); //调用外部类中的puffBall方法 p.puffBall(); } 8、包通常使用公司网址反写,可以有多层包,包名采用全部小写字母,多层包之间用”.”连接类中包的声明格式: package 包名.包名.包名…;如:黑马程序员网址itheima.com那么网址反写就为com.itheima 传智播客 itcast.cn 那么网址反写就为 cn.itcast l 注意:声明包的语句,必须写在程序有效代码的第一行(注释不算)l 代码演示:package cn.itcast; //包的声明,必须在有效代码的第一行import java.util.Scanner;import java.util.Random;public class Demo {} l import导包代码书写的位置:在声明包package后,定义所有类class前,使用导包import包名.包名.类名; 9、访问修饰符在Java中提供了四种访问权限,使用不同的访问权限时,被修饰的内容会有不同的访问权限,以下表来说明不同权限的访问能力: public protected default private同一类中 √ √ √ √同一包中(子类与无关类) √ √ √ 不同包的子类 √ √ 不同包中的无关类 √ 归纳一下:在日常开发过程中,编写的类、方法、成员变量的访问l 要想仅能在本类中访问使用private修饰;l 要想本包中的类都可以访问不加修饰符即可;l 要想本包中的类与其他包中的子类可以访问使用protected修饰l 要想所有包中的所有类都可以访问使用public修饰。l 注意:如果类用public修饰,则类名必须与文件名相同。一个文件中只能有一个public修饰的类。 10、知识点总结l final:关键字,最终的意思 final修饰的类:最终的类,不能被继承 final修饰的变量: 相当于是一个常量, 在编译生产.class文件后,该变量变为常量值 final修饰的方法: 最终的方法,子类不能重写,可以继承过来使用 l static : 关键字, 静态的意思 可以用来修饰类中的成员(成员变量,成员方法) 注意: 也可以用来修饰成员内部类 n 特点: 被静态所修饰的成员,会被所有的对象所共享 被静态所修饰的成员,可以通过类名直接调用,方便 Person.country = "中国"; Person.method(); n 注意事项: 静态的成员,随着类的加载而加载,优先于对象存在 在静态方法中,没有this关键字 静态方法中,只能调用静态的成员(静态成员变量,静态成员方法 l 匿名对象:一个没有名字的对象 n 特点: 创建匿名对象直接使用,没有变量名 匿名对象在没有指定其引用变量时,只能使用一次 匿名对象可以作为方法接收的参数、方法返回值使用 l 内部类:在一个类中,定义了一个新类,这个新的类就是内部类 class A {//外部类 class B{// 内部类 } } n 特点: 内部类可以直接访问外部类的成员,包含私有的成员 l 包的声明与访问 n 类中包的声明格式: package 包名.包名.包名…; n 带有包的类,创建对象格式:包名.类名 变量名 = new包名.类名(); cn.itcast.Demo d = new cn.itcast.Demo(); n 导包的格式: import 包名.类名; l 权限修饰符 public : 公共的 protected: 受保护的 private : 私有的 public protected 默认的 private 在当前类中 Y Y Y Y 同一包中的其他类 Y Y Y 不同包中的子类 Y Y 不同包中的其他类 Y l 代码块: 局部代码块:定义在方法中的,用来限制变量的作用范围 构造代码块:定义在类中方法外,用来给对象中的成员初始化赋值 静态代码块:定义在类中方法外,用来给类的静态成员初始化赋值

优秀的个人博客,低调大师

JAVA学习day12

1、构造方法在创建对象的时候,就有属性值——构造方法 set和get方法时对象创建后使用的 2、什么时候需要写构造方法2-1)当描述的事物在创建其对象时就要明确属性的值,这时就需要在定义类的时候书写带参数的构造方法。2-2)若创建对象时不需要明确具体的数据,这时可以不用书写构造方法(不书写也有默认的构造方法)。 没有写构造方法的:在编译时系统会自动创建一个空的构造方法class Person { //如果没有显示指定构造方法,编译会在编译时自动添加默认的构造方法 //Person(){} //空参数的默认构造方法 } 3、构造方法的格式:修饰符 构造方法名(参数列表){} 4、构造方法的体现: 构造方法没有返回值类型。也不需要写返回值。因为它是为构建对象的,对象创建完,方法就执行结束。 构造方法名称必须和类型保持一致。 构造方法没有具体的返回值。 构造方法的代码体现:class Person { // Person的成员属性age和name private int age; private String name; // Person的构造方法,拥有参数列表 Person(int a, String nm) { // 接受到创建对象时传递进来的值,将值赋给成员属性 age = a; name = nm; } } 5、构造方法的细节:1、一个类中可以有多个构造方法,多个构造方法是以重载的形式存在的2、构造方法是可以被private修饰的,作用:其他程序无法创建该类的对象。class Person { private int age; private String name; // 私有无参数的构造方法,即外界不能通过new Person();语句创建本类对象 private Person() { } // 多个构造方法是以重载的形式存在 Person(int a) { age = a; } Person(String nm, int a) { name = nm; age = a; } } 6、this调用构造方法构造方法之间的调用,可以通过this关键字来完成。l 构造方法调用格式:this(参数列表);l 构造方法的调用class Person { // Person的成员属性 private int age; private String name; // 无参数的构造方法 Person() { } // 给姓名初始化的构造方法 Person(String nm) { name = nm; } // 给姓名和年龄初始化的构造方法 Person(String nm, int a) { // 由于已经存在给姓名进行初始化的构造方法 name = nm;因此只需要调用即可 // 调用其他构造方法,需要通过this关键字来调用 this(nm); // 给年龄初始化 age = a; } } l 注意:this到底代表什么呢?this代表的是对象,具体代表哪个对象呢?哪个对象调用了this所在的方法,this就代表哪个对象。调用其他构造方法的语句必须定义在构造方法的第一行,原因是初始化动作要最先执行。 7、子父类中构造方法的调用在创建子类对象时,父类的构造方法会先执行,因为子类中所有构造方法的第一行有默认的隐式super();语句。格式:调用本类中的构造方法this(实参列表);调用父类中的空参数构造方法super();调用父类中的有参数构造方法 super(实参列表); 为什么子类对象创建都要访问父类中的构造方法?因为子类继承了父类的内容,所以创建对象时,必须要先看父类是如何对其内容进行初始化的,看如下程序:public class Test { public static void main(String[] args) { new Zi(); } }class Fu{ int num ; Fu(){ System.out.println("Fu构造方法"+num); num = 4; } }class Zi extends Fu{ Zi(){ //super(); 调用父类空参数构造方法 System.out.println("Zi构造方法"+num); } }执行结果: Fu构造方法0 Zi构造方法4 通过结果发现,子类构造方法执行时中,调用了父类构造方法,这说明,子类构造方法中有一句super()。那么,子类中的构造方法为什么会有一句隐式的super()呢?原因:子类会继承父类中的内容,所以子类在初始化时,必须先到父类中去执行父类的初始化动作。这样,才可以使用父类中的内容。当父类中没有空参数构造方法时,子类的构造方法必须有显示的super语句,指定要访问的父类有参数构造方法。 8、知识点总结l this关键字n this关键字,本类对象的引用 u this是在方法中使用的,哪个对象调用了该方法,那么,this就代表调用该方法的对象引用 u this什么时候存在的?当创建对象的时候,this存在的 u this的作用:用来区别同名的成员变量与局部变量(this.成员变量) public void setName(String name) { this.name = name; } l 构造方法: 用来给类的成员进行初始化操作n 格式: 修饰符 类名 (参数列表) { ... } n 构造方法的特点: u 1, 方法名与类名相同 u 2,没有返回值,也没有返回值类型,连void也没有 n 构造方法什么时候会被调用执行? 只有在创建对象的时候才可以被调用 l super: 指的是父类的存储空间(理解为父类的引用)调用父类的成员变量: super.成员变量; 调用父类的构造方法: super(参数); 调用方法的成员方法: super.成员方法(); l 继承中的构造方法注意事项: 1,如果我们手动给出了构造方法,编译器不会在给我们提供默认的空参数构造方法 如果我们没写任何的构造方法,编译器提供给我们一个空参数构造方法 2, 在构造方法中,默认的第一条语句为 super(); 它是用来访问父类中的空参数构造方法,进行父类成员的初始化操作 3, 当父类中没有空参数构造方法的时候,怎么办? a: 通过 super(参数) 访问父类有参数的构造方法 b: 通过 this(参数) 访问本类中其他构造方法 注意:[本类中的其他构造方法已经能够正常访问父类构造方法] 4, super(参数) 与 this(参数) 不能同时在构造方法中存在

优秀的个人博客,低调大师

JAVA学习day11

1、接口概述接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成。这样将功能的定义与实现分离,优化了程序设计。请记住:一切事物均有功能,即一切事物均有接口。 2、接口定义接口定义时需要使用interface关键字定义格式:public interface 接口名 {抽象方法1;抽象方法2;抽象方法3;}使用interface代替了原来的class,其他步骤与定义类相同:l 接口中的方法均为公共访问public的抽象方法l 接口中无法定义普通的成员变量 3、接口中成员变量的定义要求:必须定义为常量固定格式:Public static final 数据类型 变量名 = 值; 4、类与接口的关系实现关系定义类:实现接口,重写接口中的抽象方法类实现接口,可以理解为继承 关键字 implements 称为接口的实现类Class 类 implements 接口{ 重写接口中的抽象方法 } PS:只能创建接口的实现类的对象,不能创建接口的对象 /* 定义接口 使用关键字interface 接口名字 接口定义: 成员方法,全抽象 不能定义带有方法体的方法 定义抽象方法: 固定格式 public abstract 返回值类型 方法名字(参数列表); 修饰符 public 写,或者不写,都是public 接口中成员变量的定义 成员变量的定义,具体要求 要求 : 必须定义为常量 固定格式: public static final 数据类型 变量名 = 值*/ public interface MyInterface { //public static final int a = 1; //在接口中,定义抽象的方法 public abstract void function(); } ================================================/* 定义类, 实现接口,重写接口中的抽象方法 创建实现类的对象 类实现接口, 可以理解为继承 关键字 implements class 类 implements 接口{ 重写接口中的抽象方法 } 类 实现 接口 class MyInterfaceImpl implements MyInterface*/ public class MyInterfaceImpl implements MyInterface{ public void function(){ System.out.println("实现类,重写接口抽象方法"); } } =================================================测试public class Test { public static void main(String[] args) { //创建接口的实现类的对象 MyInterfaceImpl my = new MyInterfaceImpl(); my.function(); } } 5、接口中成员变量的特点6、接口中成员方法的特点 /* 接口中成员的特点 成员变量的特点, 没有变量,都是常量 固定定义格式: public static final 数据类型 变量名 = 值 public 权限 static 可以被类名直接.调用 final 最终,固定住变量的值 // * 注意: public static final 修饰符,在接口的定义中,可以省略不写 但是,不写不等于没有 三个修饰符,还可以选择性书写 接口中的成员方法特点: public abstract 返回值类型 方法名(参数列表) 修饰符 public abstract 可以不写,选择性书写 但是,写不写,都有 实现类,实现接口,重写接口全部抽象方法,创建实现类对象 实现类必须重写所有抽象方法,才能定义类对象,否则仍然是抽象类 实现类,重写了一部分抽象方法,实现类,还是一个抽象类*/ public interface MyInter { public static final int x = 3; public abstract void show(); public abstract int getSum(int a,int b); } 7、接口和抽象类的区别: 抽象类是应该有的接口是额外功能的由于犬分为很多种类,他们吼叫和吃饭的方式不一样,在描述的时候不能具体化,也就是吼叫和吃饭的行为不能明确。当描述行为时,行为的具体动作不能明确,这时,可以将这个行为写为抽象行为,那么这个类也就是抽象类。可是当缉毒犬有其他额外功能时,而这个功能并不在这个事物的体系中。这时可以让缉毒犬具备犬科自身特点的同时也有其他额外功能,可以将这个额外功能定义接口中。如下代码演示:interface 缉毒{ public abstract void 缉毒(); }//定义犬科的这个提醒的共性功能abstract class 犬科{public abstract void 吃饭();public abstract void 吼叫();}// 缉毒犬属于犬科一种,让其继承犬科,获取的犬科的特性,//由于缉毒犬具有缉毒功能,那么它只要实现缉毒接口即可,这样即保证缉毒犬具备犬科的特性,也拥有了缉毒的功能class 缉毒犬 extends 犬科 implements 缉毒{ public void 缉毒() { } void 吃饭() { } void 吼叫() { } }class 缉毒猪 implements 缉毒{ public void 缉毒() { } }相同点:l 都位于继承的顶端,用于被其他类实现或继承;l 都不能直接实例化对象;l 都包含抽象方法,其子类都必须覆写这些抽象方法;区别:l 抽象类为部分方法提供实现,避免子类重复实现这些方法,提高代码重用性;接口只能包含抽象方法;l 一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承)l 抽象类是这个事物中应该具备的内容, 继承体系是一种 is..a关系l 接口是这个事物中的额外内容,继承体系是一种 like..a关系二者的选用:l 优先选用接口,尽量少用抽象类;l 需要定义子类的行为,又要为子类提供共性功能时才选用抽象类; 8、多态多态体现为父类引用变量可以指向子类对象。多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态。在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。 如Student类可以为Person类的子类。那么一个Student对象既可以赋值给一个Student类型的引用,也可以赋值给一个Person类型的引用 9、接口的多继承多个接口之间可以使用extends进行继承。interface Fu1{ void show(); }interface Fu2{ void show1(); }interface Fu3{ void show2(); }interface Zi extends Fu1,Fu2,Fu3{ void show3(); } 10、extends 继承Implements 实现 11、多态的定义与使用格式多态的定义格式:就是父类的引用变量指向子类对象父类类型 变量名 = new 子类类型();变量名.方法名();l 普通类多态定义的格式父类 变量名 = new 子类();如: class Fu {} class Zi extends Fu {} //类的多态使用 Fu f = new Zi();l 抽象类多态定义的格式抽象类 变量名 = new 抽象类子类();如: abstract class Fu { public abstract void method(); } class Zi extends Fu { public void method(){ System.out.println(“重写父类抽象方法”); } }//类的多态使用Fu fu= new Zi();l 接口多态定义的格式接口 变量名 = new 接口实现类();如: interface Fu { public abstract void method(); }class Zi implements Fu { public void method(){ System.out.println(“重写接口抽象方法”); } }//接口的多态使用Fu fu = new Zi();l 注意事项同一个父类的方法会被不同的子类重写。在调用方法时,调用的为各个子类重写后的方法。如 Person p1 = new Student(); Person p2 = new Teacher(); p1.work(); //p1会调用Student类中重写的work方法 p2.work(); //p2会调用Teacher类中重写的work方法当变量名指向不同的子类对象时,由于每个子类重写父类方法的内容不同,所以会调用不同的方法。 12、多态中成员变量的特点 多态中,成员特点 成员变量: 编译的时候, 参考父类中有没有这个变量,如果有,编译成功,没有编译失败 运行的时候, 运行的是父类中的变量值 编译运行全看父类 成员方法: 编译的时候, 参考父类中有没有这个方法,如果有,编译成功,没有编译失败 运行的时候, 运行的是子类的重写方法 编译看父类,运行看子类如下代码 class Fu { int num = 4; }class Zi extends Fu { int num = 5; }class Demo { public static void main(String[] args) { Fu f = new Zi(); System.out.println(f.num);//输出4 Zi z = new Zi(); System.out.println(z.num);//输出5 } }l 多态成员变量 当子父类中出现同名的成员变量时,多态调用该变量时: 编译时期:参考的是引用型变量所属的类中是否有被调用的成员变量。没有,编译失败。 运行时期:也是调用引用型变量所属的类中的成员变量。 简单记:编译和运行都参考等号的左边。编译运行看左边。 13、多态中成员方法的特点class Fu { int num = 4; void show() { System.out.println("Fu show num"); } }class Zi extends Fu { int num = 5; void show() { System.out.println("Zi show num"); } }class Demo { public static void main(String[] args) { Fu f = new Zi(); f.show(); } }l 多态成员方法编译时期:参考引用变量所属的类,如果没有类中没有调用的方法,编译失败。运行时期:参考引用变量所指的对象所属的类,并运行对象所属类中的成员方法。简而言之:编译看左边,运行看右边。 14、instanceof关键字我们可以通过instanceof关键字来判断某个对象是否属于某种数据类型。如学生的对象属于学生类,学生的对象也属于人类。 用于比较引用类型使用格式:boolean b = 对象 instanceof 数据类型; 如 Person p1 = new Student(); // 前提条件,学生类已经继承了人类 boolean flag = p1 instanceof Student; //flag结果为true boolean flag2 = p2 instanceof Teacher; //flag结果为false /* 运算符比较运算符, 结果真假值 关键字, instanceof, 比较引用数据类型 Person p = new Student(); p = new Teacher() 关键字 instanceof 比较, 一个引用类型的变量,是不是这个类型的对象 p变量,是Student类型对象,还是Teacher类型对象 引用变量 instanceof 类名 p instanceof Student 比较,p是不是Student类型的对象,如果是,intanceof返回true */ public class Test { public static void main(String[] args) { Person p = new Student(); // Person p = new Teacher(); boolean b = p instanceof Student; System.out.println(b); //b = p instanceof Animal; //System.out.println(b); p.sleep(); } } 15、多态的向上转型 16、多态的向下转型父类类型强制转换为子类类型,调用子类特有的功能 17、总结下封装、继承、多态的作用:l 封装:把对象的属性与方法的实现细节隐藏,仅对外提供一些公共的访问方式l 继承:子类会自动拥有父类所有可继承的属性和方法。l 多态:配合继承与方法重写提高了代码的复用性与扩展性;如果没有方法重写,则多态同样没有意义。 18、笔记本电脑案例 1. 案例介绍 定义USB接口(具备开启功能、关闭功能),笔记本要使用USB设备,即笔记本在生产时需要预留可以插入USB设备的USB接口,即就是笔记本具备使用USB设备的功能,但具体是什么USB设备,笔记本并不关心,只要符合USB规格的设备都可以。鼠标和键盘要想能在电脑上使用,那么鼠标和键盘也必须遵守USB规范,不然鼠标和键盘的生产出来无法使用 进行描述笔记本类,实现笔记本使用USB鼠标、USB键盘 l USB接口,包含开启功能、关闭功能l 笔记本类,包含运行功能、关机功能、使用USB设备功能l 鼠标类,要符合USB接口l 键盘类,要符合USB接口 1. 案例需求分析 阶段一: 使用笔记本,笔记本有运行功能,需要笔记本对象来运行这个功能 阶段二: 想使用一个鼠标,又有一个功能使用鼠标,并多了一个鼠标对象。 阶段三: 还想使用一个键盘 ,又要多一个功能和一个对象 问题:每多一个功能就需要在笔记本对象中定义一个方法,不爽,程序扩展性极差。 降低鼠标、键盘等外围设备和笔记本电脑的耦合性。 1. 实现代码步骤 l 定义鼠标、键盘,笔记本三者之间应该遵守的规则 interface USB { void open();// 开启功能 void close();// 关闭功能 } l 鼠标实现USB规则 class Mouse implements USB { public void open() { System.out.println("鼠标开启"); } public void close() { System.out.println("鼠标关闭"); } } l 键盘实现USB规则 class KeyBoard implements USB { public void open() { System.out.println("键盘开启"); } public void close() { System.out.println("键盘关闭"); } } l 定义笔记本 class NoteBook { // 笔记本开启运行功能 public void run() { System.out.println("笔记本运行"); } // 笔记本使用usb设备,这时当笔记本对象调用这个功能时,必须给其传递一个符合USB规则的USB设备 public void useUSB(USB usb) { // 判断是否有USB设备 if (usb != null) { usb.open(); usb.close(); } } public void shutDown() { System.out.println("笔记本关闭"); } } public class Test { public static void main(String[] args) { // 创建笔记本实体对象 NoteBook nb = new NoteBook(); // 笔记本开启 nb.run(); // 创建鼠标实体对象 Mouse m = new Mouse(); // 笔记本使用鼠标 nb.useUSB(m); // 创建键盘实体对象 KeyBoard kb = new KeyBoard(); // 笔记本使用键盘 nb.useUSB(kb); // 笔记本关闭 nb.shutDown(); } } 19、知识点总结 l 接口:理解为是一个特殊的抽象类,但它不是类,是一个接口 n 接口的特点: 1,定义一个接口用interface关键字 interface Inter{} 2,一个类实现一个接口,实现implements关键字 class Demo implements Inter{} 3, 接口不能直接创建对象 通过多态的方式,由子类来创建对象,接口多态 n 接口中的成员特点: 成员变量: 只能是final 修饰的常量 默认修饰符: public static final 构造方法: 无 成员方法: 只能是抽象方法 默认修饰符: public abstract n 类与类,类与接口,接口与接口之间的关系 类与类之间:继承关系,单继承,可以是多层继承 类与接口之间: 实现关系,单实现,也可以多实现 接口与接口之间:继承关系,单继承,也可以是多继承 Java中的类可以继承一个父类的同时,实现多个接口 l 多态:理解为同一种物质的多种形态 n 多态使用的前提: 1,有继承或者实现关系 2,要方法重写 3,父类引用指向子类对象 n 多态的成员访问特点: 方法的运行看右边,其他都看左边 n 多态的好处: 提高了程序的扩展性 n 多态的弊端: 不能访问子类的特有功能 n 多态的分类 u 类的多态 abstract class Fu { public abstract void method(); } class Zi extends Fu { public void method(){ System.out.println(“重写父类抽象方法”); } } //类的多态使用 Fu fu= new Zi(); u 接口的多态 interface Fu { public abstract void method(); } class Zi implements Fu { public void method(){ System.out.println(“重写接口抽象方法”); } } //接口的多态使用 Fu fu = new Zi(); l instanceof 关键字 格式: 对象名 instanceof 类名 返回值: true, false 作用: 判断指定的对象 是否为 给定类创建的对象

优秀的个人博客,低调大师

JAVA学习day08

1、快捷键 Alt+/ 自动补全 写程序的时候,之写出一部分 输出 syso 类名 Scanner 起名字 如Int 按下alt+/会帮你带出变量 Ctrl+Shift+F 代码格式化 Ctrl+/ 单行注释 取消单行注释就再按一次 Ctrl+Shift+/ 多行注释 Ctrl+Shift+\ 取消多行注释 Ctrl+Shift+o 导入包的快捷键 Alt+上下箭头 移动当前行代码 Ctrl+alt+上下箭头 复制当前代码行 Ctrl+D 删除当前行 Ctrl+1 意见提示功能 2、调试代码 • 断点: 就是一个标记 • 如何设置断点 ○ 代码区域左边的空白位置 双击即可 • 在哪里加 ○ 想看哪个语句的执行结果就在该语句前面加 • 怎么运行断点的程序 ○ 代码区域右键 -- Debug as -- Java Application ○ 显示一个页面,提示是否进入调试页面? 是否记住当前操作?是(Yes)是(勾选复选框) • 弹出了断点页面 ○ 点哪里 § 点击 工具栏中的Step Over (执行下一行) § 快捷键F6 看到每一步程序的执行过程 ○ 看哪里 § 看代码区域: 对照看程序执行步骤 § 看Debug区域: 对照看程序执行步骤 § 看varable区域: 观察变量的创建、复制、销毁 ○ 如何消除断点 § 把设置断点的方式再执行一遍 § 切换到Debug视图,选择 Breakpoints -- Remove All Breakpoints 就是2个XX的图标 3、超市管理系统案例分析 首先需要一个功能菜单,然后输入功能序号后,调用序号对应的功能方法,实现想要的操作。分析步骤如下 ○ 1.完成超市商品初始化。创建商品,将商品添加到集合 ○ 2.显示来到超市能做的操作,也就是显示主菜单 ○ 3.根据接收到的功能选项,执行对应的功能 ○ 3.1.库存货物查询 ○ 3.2.添加新货物 ○ 3.3.删除货物 ○ 3.4.修改货物 ○ 3.5.退出系统,结束main方法的运行 ○ 4.循环,回到 2.显示主菜单 定义FruitItem类 packagecom.ghy.studyday08; /* 自定义类,描述商品信息 商品的属性 编号int 品名Strint 价格double 数量Int 总价double */ publicclassFruitItem{ //商品ID intID; // Stringname; // doubleprice; // intnumber; // doublemoney; } 定义Shopp类 packagecom.ghy.studyday08; importjava.util.ArrayList; importjava.util.Scanner; /* 超市管理系统主页 实现: 1、商品数据的初始化 2、用户的菜单选择 3、根据选择执行不同的功能 3.1Read查看商品 3.2Create创建商品 3.3Delete删除商品 3.4Update更新商品 所有功能,必须定义方法实现 主方法main调用作用 */ publicclassShopp{ publicstaticvoidmain(String[]args){ //创建ArrayList集合,存储商品类型,存输出剧类型FruitItemleixing ArrayList<FruitItem>array=newArrayList<FruitItem>(); //调用商品初始化方法,传递集合 init(array); while(true){ mainMenu(); intchoose=chooseFunction(); switch(choose){ case1: showFruitList(array); break; case2: addFruitItem(array); break; case3: deleteFruit(array); break; case4: updateFruit(array); break; case5: return; default: System.out.println("输入的序号没有"); break; } } } /** *定义方法,实现主菜单 *提示用户哪些选择,选择序号 *返回值:无 *参数:无 * * */ publicstaticvoidmainMenu(){ System.out.println(); System.out.println("===========欢迎光临ITCast超市======================"); System.out.println("1、货物清单2、添加货物3、删除货物4、更新货物5、退出"); System.out.println("请您输入要操作的功能序号"); } /** *定义方法,实现接受用户的键盘输入 *返回编号 */ publicstaticintchooseFunction(){ Scannersc=newScanner(System.in); returnsc.nextInt(); } /** *定义方法,实现显示货物清单的功能 *返回值:无 *参数:集合 *遍历集合,获取集合中的每个FruitItem变量 *变量.调用属性 */ publicstaticvoidshowFruitList(ArrayList<FruitItem>array){ System.out.println(); System.out.println("==========商品库存清单========================="); System.out.println("商品编号商品名称商品单价"); //遍历集合 for(inti=0;i<array.size();i++){ //集合get方法,获取出每个FruitItem的变量,可以使用FruitItem接受get结果 FruitItemitem=array.get(i); //变量item调用类属性 System.out.println(item.ID+""+item.name+""+item.price); } } /** * */ /** *定还是那个方法,实现商品数据的初始化 *先将一部分数据,存储到集合中 *返回值:无 *参数:集合 *方法名:init * */ publicstaticvoidinit(ArrayList<FruitItem>array){ //创建出多个FruitItem类型,并且属性赋值 FruitItemf1=newFruitItem(); f1.ID=9527; f1.name="烧饼"; f1.price=12.7; FruitItemf2=newFruitItem(); f2.ID=9528; f2.name="米粉"; f2.price=22; FruitItemf3=newFruitItem(); f3.ID=9830; f3.name="新疆大盘鸡"; f3.price=100.6; //将创建的3个FriutItem类型的变量,存储到集合中 array.add(f1); array.add(f2); array.add(f3); } /** *定义方法,实现商品的添加功能 *返回值:无 *参数:集合 *提示用户选择的是商品的功能 * *提示用户输入的是什么 * *创建FruitItem变量,变量调用的属性 *将输入的每个商品属性进行赋值 * */ publicstaticvoidaddFruitItem(ArrayList<FruitItem>array){ System.out.println("您选择的是添加商品功能"); //创建Scanner变量 Scannersc=newScanner(System.in); System.out.println("请输入商品的编号"); //输入商品的编号 intID=sc.nextInt(); //输入商品的名字 System.out.println("请输入商品的名字"); Stringname=sc.next(); //输入商品的单价 System.out.println("请输入商品的单价"); doubleprice=sc.nextDouble(); //创建FruitItem的变量 FruitItemitem=newFruitItem(); item.ID=ID; item.name=name; item.price=price; array.add(item); } /* *定义方法,实现商品的修改功能 *返回值:无 *参数: 集合 * *提示用户选择的是修改功能 *提示用户输入需要修改的商品编号 *遍历集合,获取每个FruitItem变量 *变量调用ID属性,属性和用户输入的编号比较 *如果相同: *修改调FruitItem中的属性值 *键盘输入 */ publicstaticvoidupdateFruit(ArrayList<FruitItem>array){ System.out.println("选择的是修改功能"); System.out.println("请输入商品的编号"); Scannersc=newScanner(System.in); intID=sc.nextInt(); //遍历集合,获取每个FruitItem变量 for(inti=0;i<array.size();i++){ FruitItemitem=array.get(i); //获取FruitItem的属性ID,和用户输入的ID比较 if(item.ID==ID){ System.out.println("输入新的商品编号"); item.ID=sc.nextInt(); System.out.println("输入新的商品名字"); item.name=sc.next(); System.out.println("输入新的商品价格"); item.price=sc.nextDouble(); System.out.println("商品修改成功"); return; } } System.out.println("输入的编号不存在"); } /** *定义方法,实现商品的删除功能 *返回值:无 *参数:集合 * *删除依靠的是商品的编号 *提示用户选择的是删除功能 *键盘输入商品的编号 *遍历集合,获取集合中的每个FruitItem变量 *变量调用属性ID,和用户的输入的编号,对比,相同就删除 */ publicstaticvoiddeleteFruit(ArrayList<FruitItem>array){ System.out.println("选择的是删除功能"); System.out.println("请输入商品的编号"); Scannersc=newScanner(System.in); intID=sc.nextInt(); //遍历集合 for(inti=0;i<array.size();i++){ //获取到每个FruitItem变量 FruitItemitem=array.get(i); //变量,调用属性ID,和用户输入的编号比较 if(item.ID==ID){ //移除集合中的元素 //集合的方法remove实现 array.remove(i); System.out.println("删除成功"); return; } } System.out.println("你输入的编号不存在"); } }

优秀的个人博客,低调大师

JAVA学习day07

1、奇数求和练习packagecom.ghy.studyday07; /*要求:计算1-100之间的所有的奇数和1+3+5+7...+99 有1个数据,从0变到100循环int=0<=100++从0-100,范围内,找到奇数数%2==1奇数所有的奇数求和计算需要变量,保存奇数的求和 实现步骤:1.程序可以使用到的数据,预先定义好变量需要求的奇数和2.利用循环,让变量从0变化到1003.判断变量的变化情况是不是奇数4.如果是奇数,和预先定义好的变量,求和*/publicclassLoopTest{publicstaticvoidmain(String[]args){//定义变量,保存求和intsum=0;//for循环,循环中的变量,0-100for(inti=0;i<=100;i++){//对循环的变量,进行奇数的判断,%2==1if(i%2==1){//对奇数求和sum+=i;}}System.out.println(sum); //sum=0; /*for(inti=1;i<=100;i+=2){sum+=i;}System.out.println(sum);*/}} 2、计算出水仙花数即 3位数本身 = 百位数立方 + 十位数立方 + 个位数立方三位数100-999个位数的立方+十位数的立方+百位数的立方=自己本身153=111+555+333已知三位数123获取出每个数位利用除法,取模运算 实现步骤:1.定义变量才存储三个数位上的整数2.利用循环,循环中的变量,从100变化到9993.循环中得到三位数,利用算法,拆解成三个单独数位4.将三个数位立方的求和计算,计算后的求和,和他自己进行比较判断相同,就是水仙花publicclassLoopTest_1{publicstaticvoidmain(String[]args){//定义三个变量intbai=0;intshi=0;intge=0; //循环,循环变量从100-999for(inti=100;i<1000;i++){//对i,进行计算,获取出三个数位//获取百位bai=i/100;//获取十位shi=i/10%10;//获取个位ge=i%10;//对三个数位进行立方求和if(baibaibai+shishishi+gegege==i){System.out.println(i);}}}} 3、ASCII编码表数字0-9对应ASCII编码十进制为48-57, 字母a-z对应ASCII编码十进制为97-122,字母A-Z对应ASCII编码十进制为65-90 4、利用for循环打印字母表 /*利用循环,输出字母包含大写小写,52个输出A-Za-z利用编码表实现,字母和数字的对应关系A-Z65-90a-z97-122 实现步骤:1.定义变量,保存小写a,大写A2.循环26次,输出定义好的变量每次循环,变量++*/publicclassLoopTest_2{publicstaticvoidmain(String[]args){//定义变量,保存2个字母charxiaoXie='a';chardaXie='A';//定义循环,次数26次for(inti=0;i<26;i++){//输出保存字母的变量System.out.println(xiaoXie+""+daXie);daXie++;xiaoXie++;}}} 5、利用for循环打印9*9表for循环的特点: 外循环,行数 内循环,每行的个数 /*利用嵌套for循环,实现99乘法表示实现步骤:1.定义外循环控制行数2.内循环控制个数,个数,每次都在递增3.循环中输出,乘法表的格式1*3=3*/publicclassLoopTest_3{publicstaticvoidmain(String[]args){print99(9);} publicstaticvoidprint99(intn){//定义外循环,循环9次for(inti=1;i<=n;i++){//定义内循环,每次递增,循环条件,<=ifor(intj=1;j<=i;j++){//按照标准格式,输出打印System.out.print(j+""+i+"="+ij+"t");}System.out.println();}}} 6、实现数组的遍历 7、数组的逆序 不等于反向遍历 逆序的实现思想,数组最远端位置的交换 数组的指针思想: 就是数组的索引 指针是可以随时指向数组的任意一个索引的 需要两个指针 一个大指针,一个小指针 大指针=最大索引 小指针=0索引 8、选择排序原理selectSort数组中的每个元素,和其他元素进行比较换位置 元素换位需要借助第三方变量packagecom.ghy.studyday07; /*数组的排序:一般都是升序排列,元素,小到大的排列 两种排序的方式选择排序:数组的每个元素都进行比较冒泡排序:数组中相邻元素进行比较规则:比较大小,位置交换*/publicclassArrayMethodTest_2{publicstaticvoidmain(String[]args){int[]arr={3,1,4,2,56,7,0};//调用选择排序方法//selectSort(arr); //调用冒泡排序方法bubbleSort(arr);printArray(arr);}/*定义方法,实现数组的冒泡排序返回值:没有参数:数组*/publicstaticvoidbubbleSort(int[]arr){for(inti=0;i//每次内循环的比较,从0索引开始,每次都在递减for(intj=0;j//比较的索引,是j和j+1if(arr[j]>arr[j+1]){inttemp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}}} /*定义方法,实现数组的选择排序返回值:没有参数:数组实现步骤:1.嵌套循环实现排序外循环,控制的是一共比较了多少次内循环,控制的是每次比较了多少个元素2.判断元素的大小值小值,存储到小的索引*/publicstaticvoidselectSort(int[]arr){for(inti=0;i//内循环,是每次都在减少,修改变量的定义for(intj=i+1;j//数组的元素进行判断if(arr[i]>arr[j]){//数组的换位inttemp=arr[i];arr[i]=arr[j];arr[j]=temp;}}}} /*定义方法,实现功能返回值:void方法参数:数组*/publicstaticvoidprintArray(int[]arr){//输出一半中括号,不要换行打印System.out.print("[");//数组进行遍历for(inti=0;i//判断遍历到的元素,是不是数组的最后一个元素//如何判断循环变量到达length-1if(i==arr.length-1){//输出数组的元素和]System.out.print(arr[i]+"]");}else{//不是数组的最后一个元素,输出数组元素和逗号System.out.print(arr[i]+",");}}System.out.println();}} 9、冒泡排序功能数组的相邻元素换位置1.嵌套循环实现排序外循环,控制的是一共比较了多少次内循环,控制的是每次比较了多少个元素10、数组的折半查找前提:被查找的数组中的元素,必须有序排列

优秀的个人博客,低调大师

JAVA学习day06

1、3种引用类型 1、数组 2、类 3、接口 2、定义类: 使用类的形式,对现实中的事物进行描述 事物:方法,属性 方法:这个事物具备的功能 属性:变量 格式: Public class 类名{ 属性定义 修饰符 数据类型 变量名 =值 方法定义 修饰符 返回值类型 方法名(参数列表){ } } 3、创建引用类型的变量的格式 数据类型 变量名 =new 数据类型(); 4、实现引用类型的步骤 1、导入包;如果类都是在同一个文件夹,不需要导入包; 2、创建引用类型的变量 3、变量.类型中的功能(也可以调用类中的属性,属性就是变量,赋值和获取值) 测试手机类: /* 定义类: 使用类的形式,对现实中的事物进行描述 事物: 方法,属性 方法: 这个事物具备的功能 属性: 变量 格式: public class 类名{ 属性定义 修饰符 数据类型 变量名 = 值 方法定义 修饰符 返回值类型 方法名(参数列表){ } } 要求: 使用Java中的类,描述生活中的手机这个事物 手机事物,具备哪些属性, 属于他自己的特性 颜色,品牌, 大小 */ public class Phone{ /* 定义手机的属性 */ String color ; String brand ; double size ; } 测试手机类: /* 测试,刚定义好的Phone类 创建引用类型变量的格式 数据类型 变量名 = new 数据类型(); 实现引用类型的步骤 1: 导入包 , 类都是在同一个文件夹,不需要导入包 2: 创建引用类型的变量 3: 变量.类型中的功能 */ public class TestPhone{ public static void main(String[] args){ // 2: 创建引用类型的变量 Phone p = new Phone(); //System.out.println(p); //输出内存的地址 //3: 变量.类型中的功能 //变量 p.的方式,调用类中的属性 //属性就是变量 , 赋值和获取值 p.color = "土豪金"; p.brand = "爱立信"; p.size = 5.0; //获取属性值 System.out.println(p.color+" "+p.brand+" "+p.size); } } 4、程序运行流程 1、方法先进方法区,数据共享区 2、运行时,进入栈 3、引用相关进入堆 5、两个引用类型变量内存图 6、类的练习 电饭锅,包含属性(品牌、容量大小、颜色等) 定义类,描述事物,电饭锅 属性:品牌,大小,颜色 定义类,类名字,电饭锅 类的范围,定义三个属性 7、ArrayList——ArrayList集合的使用 也是引用数据类型 步骤: 1. 导入包 java.util包中 2. 创建引用类型的变量 数据类型< 集合存储的数据类型> 变量名 = new 数据类型 <集合存储的数据类型> (); 集合存储的数据类型: 要将数据存储到集合的容器中 创建集合引用变量的时候,必须要指定好,存储的类型是什么 ArrayList<String> array = new ArrayList<String>(); 3. 变量名.方法 注意: 集合存储的数据,8个基本类型对应8个引用类型 存储引用类型,不存储基本类型 8、ArrayList的常见方法 add(参数) 向集合中添加元素,数据存储进去 方法中的参数类型,定义集合对象时候的类型是一致 ArrayList<Integer> array = new ArrayList<Integer>(); array.add(3); get(int index) 取出集合中的元素,get方法的参数,写入索引 size() 返回集合的长度, 集合存储元素的个数 补充方法: Add(int 索引,存储的元素) 将元素添加到指定的索引上 如:array.add(2,7);//在2索引的位置添加7 set(int 索引,修改后的元素) 将指定的索引上的元素进行修改 Remove(int 索引) 删除指定索引上的元素 Clear() 清空集合中的所有元素 9、ArrayList集合的遍历 /* 集合的遍历 实现思想也是索引思想 集合的索引从0开始,到 size()-1 方法get(int index) */ import java.util.ArrayList; public class ArrayListDemo_2{ public static void main(String[] args){ ArrayList<Integer> array = new ArrayList<Integer>(); array.add(121); array.add(125); array.add(123); array.add(120); array.add(128); //对集合进行遍历 //使用方法 size+get组合进行遍历 for(int i = 0 ; i < array.size(); i++){ System.out.println( array.get(i) ); } } } 10、ArrayList存储的是类型,如商品类型/* 定义,.描述商品的类 商品 4个属性 商品名字 大小 价格 库存 String double double int 定义类,类名Goods 这个类型的变量,存储到集合中 */public class Goods{ //定义商品名字 String brand ; //大小属性 double size ; // 价格属性 double price ; //库存属性 int count ; } /* 实现库存管理案例: 1. 存储商品信息 存储商品类型变量 将商品类型的变量,存储到集合中 2. 查看库存清单 将集合进行遍历, 获取出集合中存储的Goods类型变量 输出每一个Goods类型的属性 计算求和: 总库存,总金额 3. 修改商品的库存 集合遍历 ,获取出集合中存储的Goods类型变量 变量调用Goods类的属性count,值进行修改 (键盘输入) *///import java.util.ArrayList;import java.util.*;public class Shopp{ public static void main(String[] args){ //创建ArrayList集合,存储Goods类型 ArrayList<Goods> array = new ArrayList<Goods>(); //调用添加商品信息的方法 addGoods(array); //进入死循环中 while(true){ //调用选择功能的方法,获取到用户输入的功能序号 int number = chooseFunction(); //对序号判断,如果=1 进入查看库存功能 = 2 进入修改库存功能 =3 结束 switch(number){ case 1: //进入查看库存,调用查看库存的方法,传递存储商品信息的集合 printStore(array); break; case 2: //进入修改库存功能,调用修改库存的方法,传递集合 update(array); break; case 3: return ; default: System.out.println("无此功能"); break; } } } /* 方法定义,修改库存 键盘的输入,将Goods中的属性值,修改 */ public static void update(ArrayList<Goods> array){ Scanner sc = new Scanner(System.in); //遍历集合,获取集合中的每个元素 for(int i = 0 ; i < array.size(); i++){ //集合方法get获取的是集合的元素,元素类型Goods Goods g = array.get(i); System.out.println("请输入"+g.brand+"的库存数"); //Goods属性,count进行修改 g.count = sc.nextInt(); } } /* 定义方法,实现选择菜单,用户根据功能选择菜单 */ public static int chooseFunction(){ System.out.println("-------------库存管理------------"); System.out.println("1.查看库存清单"); System.out.println("2.修改商品库存数量"); System.out.println("3.退出"); System.out.println("请输入要执行的操作序号:"); Scanner sc = new Scanner(System.in); int number = sc.nextInt(); return number; } /* 定义方法,查看库存清单,遍历集合 */ public static void printStore(ArrayList<Goods> array){ //输出表头 System.out.println("----------商场库存清单----------"); System.out.println("品牌型号 尺寸 价格 库存数"); //定义变量,保存总库存数,和总金额 int totalCount = 0 ; double totalMoney = 0; //遍历集合 for(int i = 0 ; i < array.size(); i++){ //get(索引)获取出集合中的元素,存储的是Goods类,获取的也是Goods类型 //使用Goods类型变量,接受get方法结果 Goods g = array.get(i); System.out.println(g.brand+" "+g.size+" "+g.price+" "+g.count); totalCount = totalCount+g.count; totalMoney = totalMoney + g.count*g.price; } System.out.println("总库存数: "+totalCount); System.out.println("商品库存总金额: "+totalMoney); } /* 定义方法,将商品的信息存储到集合中 集合是所有方法的共享数据,参数传递 */ public static void addGoods (ArrayList<Goods> array){ //创建商品类型变量 Goods类型的变量 Goods g1 = new Goods(); Goods g2 = new Goods(); g1.brand = "MacBook"; g1.size = 13.3; g1.price = 9999.99; g1.count = 3; g2.brand = "Thinkpad"; g2.size = 15.6; g2.price = 7999.99; g2.count = 1; //Goods类型的变量,存储到集合中 array.add(g1); array.add(g2); } }

优秀的个人博客,低调大师

JAVA学习day05

1、方法就是用来完成解决某件事件或者实现某个功能的办法。 2、方法的定义格式: 修饰符 返回值类型 方法的名字 (参数列表....){ 方法的功能主体 循环,判断,变量,比较,运算 return ; } 修饰符:固定写法 public static 返回值类型: 方法在运算后,结果的数据类型 方法名: 自定义名字,满足标识符规范,方法名字首字母为小写,后面每个单词首字母大写 参数列表: 方法的运算过程中,是否有未知的数据,如果有未知的数据,定义在参数列表上(定义变量) return: 方法的返回,将计算的结果返回,结束方法 3、调用方法:让一个方法运行起来 4、调用方法执行流程 方法参数里面的都是形参 实际调用时的参数是实参 5、方法调用的内存图 栈:先进后出 后进先出 6、方法定义和使用的注意事项 1、方法不能定义在另一个方法的里面; 2、写错方法名字; 3、写错了参数列表; 4、方法返回值是void,方法中可以省略return不写; Return 后面不能有代码; 5、方法返回值类型,和return 后面数据类型必须匹配; 6、方法重复定义问题; 7、调用方法的时候,返回值是void,不能写在输出语句中; 7、方法的重载 方法的重载特性(overload) 在同一个类中,允许出现同名的方法,只要方法的参数列表不同即可,这样方法就是重载 参数列表不同:参数的个数,数据类型,顺序 对于重载的调用,根据参数传递进行区分 8、方法重载的注意事项 1、参数列表必须不同 2、重载和参数变量名无关 3、重载和返回值类型无关 4、重载和修饰符无关 技巧:重载看方法名和参数列表 9、方法参数是基本数据类型 方法,调用中的参数传递问题 1、方法参数是基本数据类型 2、方法参数是引用类型:传递的是内存地址 10、库存练习package com.ghy.study; /* 实现商品的库存管理 功能: 1. 展示用户选择功能清单 2. 根据选择的功能编号,进行不同的操作 A. 展示所有库存 B. 修改库存数量 分析: 1. 展示用户清单: 输出语句, 用户输入, 选择功能序号 2. 根据选择,调用不同的方法 switch语句 case 1 2 3 A 展示库存 将存储商品的数组,遍历 B 修改库存 修改所有的库存数量 */import java.util.Scanner; public class ShopMethod { public static void main(String[] args){ //使用数组,保存商品的信息 //品名,尺寸,价格,库存数, 定义5个数组 String[] brand = {"MacBookAir","ThinkpadT450"}; double[] size = {13.3,15.6}; double[] price = {9998.97,6789.56}; int[] count = {0,0}; while(true){ int choose = chooseFunction(); switch(choose){ case 1: //调用查看库存清单方法 printStore(brand,size,price,count); break; case 2: //调用修改库存的方法 update(brand,count); break; case 3: return ; default: System.out.println("没有这个功能"); break; } } } /* 定义方法,修改所有商品的库存 用户输入1个,修改1个 返回值,没有 参数, 库存数的数组, 品名数组 */ public static void update(String[] brand, int[] count){ //遍历数组,遍历到一个,修改一个 //接受键盘输入 Scanner sc = new Scanner(System.in); //遍历数组 for(int i = 0; i < brand.length ; i++){ System.out.println("请输入"+brand[i]+"的库存数"); //键盘输入,录入库存, 存储到库存的数组中 int newCount = sc.nextInt(); count[i] = newCount; } //int chooseNumber = sc.nextInt(); } /* 定义方法,展示所有的库存清单,遍历 返回值,没有 参数, 数组 */ public static void printStore(String[] brand,double[] size,double[] price,int[] count){ System.out.println("----------商场库存清单----------"); System.out.println("品牌型号 尺寸 价格 库存数"); //定义变量,计算总库存数,和总价格 int totalCount = 0; int totalMoney = 0; //遍历数组,将数组中所有的商品信息打印出来 for(int i = 0 ; i < brand.length ; i++){ System.out.println(brand[i]+" "+size[i]+" "+price[i]+" "+count[i]); totalCount += count[i]; totalMoney += count[i]*price[i]; } System.out.println("总库存数: "+totalCount); System.out.println("商品库存总金额: "+totalMoney); } /* 定义方法,实现用户的选择功能,功能的需要返回来 返回值, int 参数, 没有 */ public static int chooseFunction(){ System.out.println("-------------库存管理------------"); System.out.println("1.查看库存清单"); System.out.println("2.修改商品库存数量"); System.out.println("3.退出"); System.out.println("请输入要执行的操作序号:"); //接受键盘输入 Scanner sc = new Scanner(System.in); int chooseNumber = sc.nextInt(); return chooseNumber; } }

优秀的个人博客,低调大师

JAVA学习day04

1、选择语句switch编写格式Switch( 表达式 ){ Case 常量1: 要执行的语句; Break; Case 常量2: 要执行的语句; Break; Case 常量3: 要执行的语句; Break; Default: 要执行的语句; Break; }执行流程:表达式,和case后面的常量进行比较和哪个case后的常量相同,就执行哪个case后面的程序,遇到break,就全部结束; 2、case的穿透性案例:星期1-5 工作日 星期6-7 输出休息日case 1 case 2 case 3 case 4 case 5 输出结果相同 case后面的常量,和switch中数据相同,没有break,一直向下穿透case后面没有break,程序就会一直向下穿透 3、数组数据多了存数组(原因:数据太多,定义变量,容易造成代码重复) 定义数组容器 定义数组容器,要素,强制数据类型的语言 必须要有数据类型,大小,就是存储数据的个数 定义数组公式: 数组类型 [] 变量名 = new 数据类型 [存储元素的个数] 数据类型:数组中存储元素的数据类型 [] 表示数组的意思 变量 自定义标识符 New 创建容器关键字 数据类型:数组中存储元素的数据类型 [] 表示数组的意思 元素个数,就是数组中,可以存储多少个数据(恒定,数组是定长型) 数组是一个容器:存储到数组中的每个元素,都有自己的额自动编号 自动编号,最小值是0,最大值,长度-1 自动编号专业名词,索引(index),下表,角标 访问数组存储的元素,必须依赖于索引,公式 数组名[索引] JAVA提供了一个属性,操作索引的 数组的一个属性,就是数组的长度,属性的名字 Length 使用属性: 数组名.length 数据类型 Int 数组的最小索引是0 最大索引是数组.length-1 4、JVM的内存划分 5、 其中:arr引用类型,保存的数据,实质上是内存中的地址; 6、为数组的元素赋值Arr[1]=5 7、数组的定义数组的两个定义方式 数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3} ; Int[] arr =new int[] {1,2,3,4,5,6,7} 数据类型[] 变量名 ={匀速1,元素2,元素3}; //定义数组,直接大括号赋值这种方式推荐使用 int[]arr2={1,2,3,4,5,8}; System.out.println(arr2.length);//打印数组的长度 System.out.println(arr2[5]);//索引从0开始 8、数组的遍历 通过索引的方式将数组中的每个元素,分别获取出来 要依靠索引才能实现 //如下方式是遍历数组最常用的方式 for(inti=0;i<arr.length;i++){ System.out.println(arr[i]); } 9、数组中常见的异常 数组的索引越界异常 空指针异常 10、数组获取最值得原理思想 1)定义变量,保存在数组中 Int max =arr[0]; 2)max和数组中的其他元素进行比较 A 数组遍历 B max比其他索引上的元素小 max记录下较大的数 3)数组遍历完成后 max记录的就是数组的最大值 publicclassArrayDemo_5{ publicstaticvoidmain(String[]args){ //定义数组,Intleixing int[]arr={5,2,3,5,8,9,0,4}; //定义变量,记录数组中0索引上的元素 intmax=arr[0]; //遍历数组,获取所有的元素,和变量max比较 for(inti=1;i<arr.length;i++){ //变量max,和数组中的每个元素进行比较 //如果Max小于了数组中的一个元素,将较大的元素赋值给max if(arr[i]>max){ max=arr[i]; } } //遍历完成,变量max就是数组的最大值 System.out.println(max); } } 11、二维数组的定义 11、二维数组的定义和访问 12、二维数组的遍历 13、维数组的遍历求和 /* 二维数组的遍历求和 第一小组销售额为{11,12}万元 第二小组销售额为{21,22,23}万元 第三小组销售额为{31,32,33,34}万元。 每个小组就是一个数组,三个数组存储到一个数组中,形成二维数组 求和: 每个小组求和 所有元素求和 */ publicclassArrayArrayDemo_3{ publicstaticvoidmain(String[]args){ int[][]arr={{11,12},{21,22,23},{31,32,33,34}}; //定义变量,保存2个求和的值 intsum=0;//所有元素的求和 intgroupSum=0;//每个一维数组的求和 for(inti=0;i<arr.length;i++){ for(intj=0;j<arr[i].length;j++){ //将一维数组的元素求和 groupSum+=arr[i][j]; } System.out.println("每个小组总金额"+groupSum); //将每个一维数组的总和在相加 sum+=groupSum; //每个唯一数组求和,清空 groupSum=0; } System.out.println("本公司总金额"+sum); } } 14、随机点名器 packagecom.ghy.study; /* 随机点名器: 1存储姓名 2.预览所有人的姓名 3.随机出一个人的姓名 */ importjava.util.Random; publicclassCallName{ publicstaticvoidmain(String[]args){ //存储姓名,姓名存储到数组中 //数组存储姓名,姓名的数据类型,String String[]names={"张三","李四","王五","李蕾","韩梅梅","小名","老王","小华","约翰逊","爱丽丝"}; //预览:遍历数组,打印所有姓名 for(inti=0;i<names.length;i++){ System.out.println(names[i]); } System.out.println(names.length); System.out.println("============="); //随机出一个人的名 //利用随机数,生成一个整数,作为索引,到数组中找到对应的元素 Randomran=newRandom(); //随机数,范围必须是0-数组的最大索引 //nextInt是0-这个数,但不包含这个数 intindex=ran.nextInt(names.length);//index就是随机数,作为索引 System.out.println(names[index]); } }

优秀的个人博客,低调大师

JAVA学习day03

1、引用类型变量格式:类型 变量名=new 类型();举例:Scanner sc=new Sccanner();每个引用类型,都有自己的功能,如何使用功能格式:变量.方法名() 2、util 工具的意思 3、Scanner类,作用,让我们在命令行中,接收键盘的输入 使用Scanner类的步骤: 1、导入包,知名类所在的文件夹 java文件夹的util文件夹 2、公式,创建出Scanner类型变量 3、变量.使用Scanner类中的功能,完成键盘输入 4、随机数java中已经有的引用类型Random类步骤:1、导入包,Random类,在java.util文件夹2、公式:创建Random类型的变量3、变量.调用Random类中的功能,产生随机数 Random类,提供功能,名字,nextInt()产生一个随机数,结果是Int类型出现随机数的范围,在功能netxint()(写一个整数),整数:随机出来的范围随机数的范围0-指定的整数间的随机数nextInt(100)0-99 5、if语句 /***if语句*编写格式:*if(条件){*if语句的执行体*}*条件:结果必须是布尔类型1==1true||false*执行体:当if中的条件为true的时候,执行大括号中的执行体*if条件是false的时候,不执行****/publicclassIfDemo{publicstaticvoidmain(String[]args){inti=5;if(i==5){System.out.println("if中的条件是true");i++;}System.out.println(i); } } 6、if…else语句 7、三元运算符判断条件?表达式1:表达式2如果条件为真,则表达式1;如果为假,则表达式2 8、while循环编写格式:While(条件){ 循环体 }条件:当条件是true,就执行循环体,执行虚幻提后程序再次执行whie中德条件,如果条件还是true,继续执行循环体,直到条件是false的时候,循环就结束。 9、for循环编写格式For(初始化变量;条件;增量){ 循环体 } 10、do…while循环编写格式: Do{ 循环体 }while(条件) 特点:无条件先执行一次 11、嵌套循环循环里面还有虚幻,for形式多For(){ For(){ } }总循环次数=外循环次数*内循环次数 内循环是外循环的循环体 外循环,控制的是行数内循环,控制的是每行的个数 12、跳出break关键字 作用于循环中,终止循环的作用continue关键字 作用:在循环中,终止本次循环,开始下一个循环 13、猜数字游戏 package com.ghy.study; import java.util.Random;import java.util.Scanner; /** 实现猜数字的小游戏 随机数一个数字,让用户猜 结果3种情况* 随机数:Random 键盘输入:Scanner 猜的数字,和随机数进行比较if判断 直到猜中为止,反复去猜,循环while*/ public class GuestNumber { public static void main(String[] args) { System.out.println("猜数字游戏开始啦"); Random r=new Random(); Scanner sc=new Scanner(System.in); int j = r.nextInt(10); System.out.println(j); while (true) { System.out.println("请输入数据:"); int i = sc.nextInt(10); if(i == j){ System.out.println("恭喜你猜对了"); break; }else if(j > i){ System.out.println("猜小了"); }else if (j < i){ System.out.println("猜大了"); } } } }

优秀的个人博客,低调大师

JAVA学习day02

1、基本数据类型四类八种 2、变量定义后,不赋值,不能使用,即必须进行赋值后才能使用; 3、自增和自减++a 和a++相等但是在计算时,有如下差别a=3b=a++b=3,a=4 若a=3c=++ac=4,a=4 4、赋值 5、打印清单实现商品库存清单案例步骤:1、实现表头,是固定数据,直接写输出语句;2、表格中间,商品数据,采用变量形式,定义变量,找对数据类型,输出所有变量3、表格尾巴,一部分数据固定另一部分:商品数据进行数学计算 */ public class Shop { public static void main(String[] args) { //输出表头固定数据 System.out.println("---------商品库存清单-----------"); System.out.println("品牌型号 尺寸 价格 库存数"); //定义表格中的数据变量 //品牌型号String 尺寸,价格double 库存int String macBrand="MacBookAir"; double macSize=13.3; double macPrice=6898.88; int macCount=5; String thinkBrand="ThinkPadT450"; double thinkSize=14; double thinkPrice=5999.88; int thinkCount=10; String asusBrand="ASUS-FL5800"; double asusSize=15.6; double asusPrice=4999.5; int asusCount=18; System.out.println(macBrand+" "+macSize+" "+macPrice+" "+macCount); System.out.println(thinkBrand+" "+thinkSize+" "+thinkPrice+" "+thinkCount); System.out.println(asusBrand+" "+asusSize+" "+asusPrice+" "+asusCount); //计算库存总数,所有商品数量库存求和 int totalCount=macCount+thinkCount+asusCount; //计算所有商品的总金额,每个商品价格*库存数 double totalMoney=macCount*macPrice+thinkCount*thinkPrice+asusCount*asusPrice; System.out.println("总库存数:"+totalCount); System.out.println("所有商品的总金额:"+totalMoney); } }

优秀的个人博客,低调大师

JavaScript学习(十六)----事件处理

目录 事件与事件处理概述 事件与事件名称 JavaScript的常用事件 JavaScript的相关事件 事件处理程序的调用 1.在JavaScript中 代码: 2.在HTML中 JavaScript是基于对象(object-based)的语言,它的一个最基本的特征就是采用事件驱动(event-driven)。可以使在图形界面环境下的一切操作变得简单化。通过鼠标或热键的动作称为事件(event)。由鼠标或热键引发的一连串程序动作,称为事件驱动(event driver),而对事件进行处理的程序或函数,称为事件处理程序(event handler)。 事件与事件处理概述 事件处理是对象化编程的个很重要的环节,它可以使程序的逻辑结构更加清晰,使程序更具有灵活性,提高了程序的开发效率。事件处理的过程分为三步:①发生事件;②启动事件处理程序;③事件处理程序做出反应。其中,要使事件处理程序能够启动,必须通过指定的对象来调用相应的事件,然后通过该事件调用事件处理程序。事件处理程序可以是任意JavaScript语句,但是一般用特定的自定义函数(function) 来对事件进行处理。 事件与事件名称 事件是一些可以通过脚本响应的页面动作。当用户按下鼠标键或者提交一个表单, 甚至在页面上移动鼠标时,事件就会出现。事件处理是一段 JavaScript代码,总是与页面中的特定部分以及一定的事件相关联。当与页面特定部分关联的事件发生时,事件处理器就会被调用。 绝大多数事件的命名都是描述性的,很容易理解。例如click. submit. mousecover 等,通过名称就可以猜测其含义。但也有少数事件的名称不易理解,例如blur (英文的字面意思为“模糊”),表示一个域或者 一个表单失去焦点。通常,事件处理器的命名原则是, 在事件名称前加上前缀on.例如,对于click事件,其处理器名为onclick. JavaScript的常用事件 JavaScript的相关事件 事件 说明 鼠标键盘事件 onclick 鼠标单击时触发此事件 ondblclick 鼠标双击时触发此事件 onmousedown 按下鼠标时触发此事件 onmouseup 鼠标按下后松开鼠标时触发此事件 onmouscover 当鼠标移动到某对象范围的上方时触发此事件 onmousemove 鼠标移动时触发此事件 onmouscout 当鼠标离开某对象范围时触发此事件 onkeypress 当键盘上的某个键被按下并且释放时触发此事件 onkeydown 当键盘上某个按键被按下时触发此事件 onkeyup 当键盘上某个按键被按下后松开时触发此事件 页面相关事件 onabort 图片在下载时被用户中断时触发此事件 onbeforeunload 当前页面的内容将要被改变时触发此事件 onerror 出现错误时触发此事件 onload 页面内容完成时触发此事件(也就是页面加载事件) onresize 当浏览器的窗口大小被改变时触发此事件 onunload 当前页面将被改变时触发此事件 事件 说明 表单相关事件 onblur 当前元素失去焦点时触发此事件 onchange 当前元素失去焦点并且元素的内容发生改变时触发此事件 onfocus 当某个元素获得焦点时触发此事件 onreset 当表单中RESET的属性被激活时触发此事件 onsubmit 一个表单被递交时触发此事件 滚动字幕事件 onbounce 在Marquce内的内容移动至Marquce品示范围之外时触发此事件 onfinish 当Marquce元素完成需婴显示的内容后触发此事件当Marquce元素开始显示内容时触发此事件 onstart Marquce元素开始显示内容时触发此事件 编辑事件 onbeforecopy 当页面当前被选择内容将要复制到浏览者系统的剪贴板前触发此事件 onbeforecut 当页面中的部分或全部内容被剪切到浏览者系统剪贴板时能发此事件 onbeforeeditfocus 当前元素将要进入编辑状态时触发此事件 onbeforepaste 当要将内容从浏览者的系统剪贴板中粘贴到页面上时触发此事件 onbeforeupdate 当浏览者粘贴系统剪贴板中的内容时通知目标对象 oncontextmenu 当浏览者按下鼠标右键出现菜单时或者通过键盘的按键触发页面菜单时触发此事件 oncopy 当页面当前的被选择内容被复制后触发此事件 oncut 当页面当前的被选择内容被剪切时触发此事件 ondrag 当某个对象被拖动时触发此事件(活动事件) ondragend 当鼠标拖动结束时触发此事件,即鼠标的按钮被释放时 ondragente 当对象被鼠标拖动进入其容器范围内时触发此事件 ondragleave 当对象被鼠标拖动的对象离开其容器范围内时触发此事件 ondragover 当被拖动的对象在另一对象容器范围内拖动时触发此事件 ondragstart 当某对象将被拖动时触发此事件 ondrop 在一个拖动过程中,释放鼠标键时触发此事件 onlosecapture 当元素失去鼠标移动所形成的选择焦点时触发此事件 onpaste 当内容被粘贴时触发此事件 onselect 当文本内容被选择时触发此事件 onselectstart 当文本内容的选择将开始发生时触发此事件 事件 说明 数据绑定事件 onafterupdate 当数据完成由数据源到对象的传送时触发此事件 oncellchange 当数据来源发生变化时触发此事件 ondataavailable 当数据接收完成时触发此事件 ondatasetchanged 数据在数据源发生变化时触发此事件 ondatasetcomplete 当数据源的全部有效数据读取完毕时触发此事件 onerrorupdate 当使用onbeforeupdate事件触发取消了数据传送时,代替afterupdate事件 数据绑定事件 onrowenter 当前数据源的数据发生变化井且有新的有效数据时触发此事件 onrowexit 当前数据源的数据将要发生变化时触发此事件 onrowsdelete 当前数据记录将被删除时触发此事件 onrowsinserted 当前数据源将要插入新数据记录时触发此事件 外部事件 onafterprint 当文档被打印后触发此事件 onbeforeprint 当文档即将打印时触发此事件 onfilterchange 当某个对象的滤镜效果发生变化时触发此事件 onhelp 当浏览者按下F1键或者单击浏览器的帮助菜单时触发此事件 onpropertychange 当对象的属性之一发生变化时触发此事件 onreadystatechange 当对象的初始化属性值发生变化时触发此事件 事件处理程序的调用 在使用事件处理程序对页面进行操作时,最重要的是如何通过对象的事件来指定事件处理程序。 1.在JavaScript中 在JavaScript中调用事件处理程序,首先需要获得要处理对象的引用,然后将要执行的处理函数赋值给对应的事件。 代码: <input id="save" name="bt_save" type="button" value="保存" /> <script language="JavaScript" type="text/javascript"> var b_save=document.getElementById("save"); b_save.onclick=function(){ alert("单击了保存按钮"); } </script> 2.在HTML中 在HTML中分配事件处理程序,只需要在HTML标记中添加相应的事件,并在其中指定要执行的代码或函数名即可。 <input name="bt_save" type="button" value="保存" onclick="clickFunction();"/> <script language="JavaScript" type="text/javascript"> function clickFunction(){ alert("单击了保存按钮"); } </script>

优秀的个人博客,低调大师

JavaScript学习(十三)---RegExp对象

目录 创建RegExp对象 1.使用RegExp的显式构造函数 2.使用RegExp的隐式构造函数,采用纯文本格式 RegExp对象的属性 静态属性: index属性: input属性: lastIndex属性: lastMath属性: lastParen属性: leftContext属性: rightContext属性: $1...$9属性: 实例属性: global属性: ignoreCase属性: multiline属性: source属性: RegExp对象的方法 1.exec()方法 语法:rgExp.exec(str) rgExp: str: 例子: 2.test()方法 语法:rgexp.test(str) 例子: 创建RegExp对象 每一条正则表达式模式对应一个RegExp实例,有两种方式可以创建RegExp对象的实例。 1.使用RegExp的显式构造函数 语法:newRegExp("pattern"[,"flags"]) //即newRegExp(" 模式 "[," 标记 "]) 2.使用RegExp的隐式构造函数,采用纯文本格式 语法:/pattern/[flags] pattern部分为要使用的正则表达式模式文本,是必选项。 flags部分设置正则表达式的标志信息,是可选项。如果设置flags部分,在第一种方式中,以字符串形式存在;在第二种方式中,以文本的形式紧接在最后一个‘/’字符之后。flags可以是一下标志字符的组合。 g是全局标志。如果设置了这个标志,对某个文本执行搜索和替换操作时,将对文本中所有匹配的部分起作用。如果不设置这个标志,则仅搜索和替换最早匹配的文本内容。 i是忽略大小写标志。如果设置了这个标志,进行匹配时将忽略大小写。 m是多行标志。如果不设置这个标志,那么元字符‘^’只与整个被搜索字符串的开始位置相匹配。而元字符‘$’只与整个被搜索字符串的结束位置相匹配。 RegExp对象的属性 RegExp对象的属性分为静态属性和实例属性。 静态属性: RegExp对象的静态属性包括index、input、lastIndex、lastMath、lastParen、leftContext、rightContext以及$1...$9。 index属性: 是当前表达式模式首次匹配内容的开始位置,从0开始计数。其初始值为-1,每次匹配成功,index属性都会随之改变。 input属性: 返回当前所作用的字符串,可以简写为$_,初始值为空字符串。 lastIndex属性: 是当前表达式模式首次匹配内容中最后一个字符的下 一个位置,从0 开始计数,常被作为继续搜索时的起始位置,初始值为1,表示从起始位置开始搜索,每次成功匹配时,lastIndex属性值都会随之改变。 lastMath属性: 是当前表达式模式的最后一个匹配字符串,可以简写为$&。其初始值为空字符串("")。在每次成功匹配时,lastMatch 属性值都会随之改变。 lastParen属性: 如果表达式模式中有括起来的子匹配,是当前表达式模式中最后的子匹配所匹配到的子字符串,可以简写为$+。其初始值为空字符串("")。每次成功匹配时,lastParen 属性值都会随之改变。 leftContext属性: 是当前表达式模式最后一个匹配字符串左边的所有内容,可以简写为$’(其中'`'为键盘上Esc键下边的反单引号)。初始值为空字符串("")。每次成功匹配时,其属性值都会随之改变。 rightContext属性: 是当前表达式模式最后一个匹配字符串右边的所有内容,可以简写为$’(其中'`'为键盘上Esc键下边的反单引号)。初始值为空字符串("")。每次成功匹配时,其属性值都会随之改变。 $1...$9属性: 这些属性是只读的。如果表达式模式中有括起来的子匹配,$1..$9 属性值分别是第1~9个子匹配所捕获到的内容。如果有超过9个以上的子匹配,$1..$9属性分别对应级后的9个子匹配。在一个表达式模式中,可以指定任意多个带括号的子匹配,但RegExp对象只能存储最后的9个子匹配的结果。在RegExp实例对象的一些方法所返回的结果数组中, 可以获得所有圆括号内的子匹配结果。 实例属性: RegExp的实例有几个只读的属性,其中global表示是否为全局匹配,ignoreCase 表示是否忽略大小写,mutiline表示是否为多行匹配,source 是正则式的源文本,如“/[ab]/g"”的源文本就是“[ab]"。另外还有“ 个可写的属性是lastIndex, 表示下次执行匹配时的起始位置。下面对这几种属性进行详细说明。 global属性: 返回创建RegExp对象实例时指定的global标志(g) 的状态。如果创建RegExp对象实例时设置了g标志,该属性返回true, 否则返回false,默认值为false. ignoreCase属性: 返回创建RegExp对象实例时指定的ignoreCase标志(i)的状态。如果创建RegExp对象实例时设置了i标志,该属性返回true,否则返回false,默认值为false. multiline属性: 返回创建RegExp对象实例时指定的multiline 标志( m)的状态。如果创建RegExp对象实例时设置了m标志,该属性返回tnue,否则返回false, 默认值为false. source属性: 返回创建RegExp对象实例时指定的表达式文本字符串。 RegExp对象的方法 1.exec()方法 exec()方法用正则表达式模式在字符串中运行查找,并返回包含该查询结果的一个数组。 语法:rgExp.exec(str) rgExp: 必选项。包含正则表达式模式和可用标志的正则表达式对象。 str: 必选项。要在其中执行查找的Sring对象或字符串文字。如果exec()方法没有找到匹配,则返回null;如果找到匹配,则exec()方法返回一个数组, 并且更新全局RegExp对象的属性,以反映匹配结果。数组的0元素包含了完整的匹配,而第1~n元素中包合的是匹配中出现的任意一个子匹配。这相当于没有设置全局标志(g) 的match()方法。 如果为正则表达式设置了全局标志,exec()方法从以lastIndex的值指示的位置开始查找:如果没有设置全局标志,exec()方法忽略lastIndex的值,从字符串的起始位置开始搜索。 exec()方法返回的数组有3个属性,分别是input、index和lastIndex。input属性包含了整个被查找的字符串。index属性中包含了整个被查找字符串中匹配的子字符串的位置。lastIndex属性包含了匹配中最后一个字符串的下一个位置。 例子: <script language="JavaScript"> function RegExpTest(){ var src="I'm a good man"; //创建正则表达式模式 var re=/\w+/g; var arr; while((arr=re.exec(src))!=null) { document.write(arr.index+"-"+arr.lastIndex+arr+"\t"); } } document.write(RegExpTest()); </script> 2.test()方法 test()方法返回一个Boolean值,指出在被查找的字符串中是否存在模式。 语法:rgexp.test(str) 例子: <script language="JavaScript"> function TestDemo(re,s){ var s1; //声明变量 //检查字符串是否存在正则表达式 if(re.test(s)){ //测试是否存在 s1 = "包含"; //s包含模式 }else{ s1="不包含"; //s不包含模式 } return("'"+s+"'"+s1+"'"+re.source+"'"); } document.write(TestDemo(/boy/,"I am a good boy")); </script>

优秀的个人博客,低调大师

java8学习:ForkJoin

内容来自《 java8实战 》,本篇文章内容均为非盈利,旨为方便自己查询、总结备份、开源分享。如有侵权请告知,马上删除。书籍购买地址:java8实战 这篇是接上一篇并行数据处理与性能余下的问题:forkjoin进行讲解的 forkjoin的目的就是以递归的方式来拆分更小的任务,然后将每个小任务处理后的结果在合并,fork就是拆分,join就是合并 RecursiveTask 要把任务提交到这个池,就必须创建 RecursiveTask的子类,R就是你需要返回的结果类型,如果不返回结果就使用RecursiveAction类型,继承这个抽象类只需要实现一个方法 protected abstract V compute(); 此方法定以了将任务拆分成子任务的逻辑,以及无法再才分或不方便拆分时生成单个子任务结果的逻辑,(它定义了咋拆分又定义了怎么把子任务聚合) 先实现一下,再来说原理 还是实现1到一千万的累加和 public class ForkJoinImpl extends java.util.concurrent.RecursiveTask<Long> { //临界值,就是结束值减开始值的结果如果小于这个值那么就不拆分了,大于这个值才会拆分 private final int MEDIAN_NUM = 100000; //从多少计算 private int start_num = 0; //计算到多少 private int end_num = 0; //构造 public ForkJoinImpl(int start_num, int end_num) { this.start_num = start_num; this.end_num = end_num; } @Override protected Long compute() { //结束值减开始值的结果 int temp = end_num - start_num; //判断结束值减开始值的结果是否小于上面定义的临界值 if (temp <= MEDIAN_NUM){ //如果小的话,那么就不进行拆分了,就直接调用方法开始计算 return sequentiallySum(); } //到这就代表结束值减开始值的结果是大于临界值的 //继续进行拆分 //start_num到start_num + temp / 2是把数据的左半部分形成一个新的task //比如0到10,那么就是 10-0=10,temp=10,start_num=0,所以形成的新task就是(0,10/2=5),也就是左半部分 ForkJoinImpl leftTask = new ForkJoinImpl(start_num,start_num + temp / 2); //利用ForkJoinPool中的线程异步执行新创建的子任务 leftTask.fork(); //这创建的就是数据的后半段,start_num + temp / 2 = 0+10/2 = 6,所以形成的新task就是(0+10/2=6,10),也就是右半部分 ForkJoinImpl rightTask = new ForkJoinImpl(start_num + temp / 2,end_num); //同时执行第二个子任务,有可能允许进一步划分 Long rightResult = rightTask.compute(); //读取第一个子任务的结果,如果没有完成就等待 Long leftResult = leftTask.join(); //该任务的结果是两个子任务结果的组合 return rightResult + leftResult; } //计算方法:在不能进行拆分的时候进行计算 private Long sequentiallySum(){ long sum = 0; for (int i = start_num; i <= end_num; i++) { sum += i; } return sum; } } @Test public void test() throws Exception { ForkJoinImpl forkJoin = new ForkJoinImpl(0, 10000000); Long invoke = new ForkJoinPool().invoke(forkJoin); System.out.println("invoke = " + invoke); } 上面的流程的总结:当把ForkJoinImpl对象传给ForkJoinPool时,这个任务就由池中的一个线程执行,这个线程会调用任务的compute方法,该方法会检查任务是够孝道足以顺序执行,也就是我们上面定义的临界值,如果不够小就会要求再次拆分数据,并分给一个新的ForkJoinImpl,新的ForkJoinImpl也是由pool安排执行。因此这个过程是递归重复的,把缘任务拆分为更小的任务。这时候达到临街值要求后,会顺序计算每个任务的结果,然后由分支过程创建的任务二叉树遍历回到它的根。接下来会合并每个子任务的部分结果,从而得到总任务的结果。如下面的图 使用此框架的最佳做法 对一个任务嗲用join方法会阻塞调用方,直到该任务做出结果,因此有必要在两个子任务的计算都开始之后在调用它,否则,你得到的版本会比原始的顺序算法更慢更复杂,因为每个子任务都必须去等待另一个任务完成才能启动 对子任务调用fork方法可以把他排进pool,同时对左边和右边的子任务调用它似乎很自然,但这样做的效率比直接对其中一个调用compute低,这样做可以以为其中一个子任务重用同一个线程,从而避免在线程池中多分配一个任务造成的开销。比如有些写 //执行子任务 left.fork(); right.fork(); //获取子任务结果 int lResult = left.join(); int rResult = right.join(); 而更高效的写法是 leftTask.fork(); ForkJoinImpl rightTask = new ForkJoinImpl(start_num + temp / 2,end_num); //自己理解的是它一直判断是否有大于临界值,如果有就左半部分进行加入pool,而右边一直去判断是否还有大于临界值的情况 //而不至于两方都在等待,并且上面的写法需要left返回后右边才会返回。如果理解的不对请评论指正 Long rightResult = rightTask.compute(); Long leftResult = leftTask.join(); 工作窃取 对于上面会产生很多的小任务然后分配到内核上进行计算,理想情况下是所有的小任务机会全部同时执行完毕,但是由于线程是随意切换的,这种情况会发生改变:可能A已经空闲了,但是B还是忙的要死,为了解决这样的一个问题,此框架就有工作窃取的技术了 在应用中,这意味着这些任务拆不多被平均分配到pool中的所有的线程上。但每个线程都为分配给他的任务保存一个双向队列,每完成一个任务,就会从队列头上取出下一个任务开始执行,当A已经忙完,B还在忙的时候,A并不会闲下来,而是随机选一个别的线程,从队列的尾巴上偷走一个任务,这个过程一直继续下去,直到所有的任务执行完毕,所有队列都情况,这就是为什么不划分为几个大任务而是很多小任务,这样有助于更好的在工作线程之间平衡负载

优秀的个人博客,低调大师

java8学习:入门

内容来自《 java8实战 》,本篇文章内容均为非盈利,旨为方便自己查询、总结备份、开源分享。如有侵权请告知,马上删除。书籍购买地址:java8实战 sync的使用成本:多核CPU的每个处理器内核都有独立的告诉缓存,加锁需要这些告诉缓存同步运行,然而这有需要在内核间进行较慢的缓存一致性协议通信 流处理 流是一系列数据项,一次只生成一项。程序可以从输入流中一个个读取数据项,然后以 相同的方式将数据项写入输出流 拿Linux的管道命令来演示流过程 如上熟悉linux都清楚cat file1 file2会创建两个文件的输出流,如果加上>那么就会生成一个合并了File1和file2的新文件,cat产生的数据流会通过管道传送给tr进行内容过滤,符合条件的又会传入下一个sort方法进行排序,最后sort排序完成的结果集交给tail -3取三行,至此流算是结束了。这些的流处理行为是高效的,因为cat的数据读一条就会传给tr过滤,tr后传入sort,sort就能在cat或tr完成前先处理几行 基于上面的思想,java8引入了Stream,这样的好处是并行能力得到了极大的提升,并且站在了更高的抽象角度去编程,因为原来的编程习惯的java只能利用一个cpu,除非自己去写thread,并且thread是容易出错的 用行为参数化把代码传递给方法 java8可以通过api传递代码。 对上面的解释就是:看到上面的图的sort函数,可能它默认的只能升序或者降序排序,但是如果我们需要定制排序的话,也就只能对sort进行重新定义,那么就比如下面(java代码演示) @Test public void test() throws Exception { List<Integer> ints = Arrays.asList(1,3,4,5,1,5,7,7,8); ints.sort(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); //升序 } }); System.out.println(ints); ints.sort(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return - o1.compareTo(o2); //降序 } }); System.out.println(ints); } 如上的代码,其实是只有renturn...是有用的,这句代码关乎到排序规则,但是其他的代码都是无用的。那么这时候就会想,只需要写一遍匿名内部类,排序逻辑根据自己需要传入不就行了。这个思想就是:通过api传递代码 并行与共享的可变数据 并发和并行的概念 并发是两个任务可以在重叠的时间段内启动,运行和完成。并行是任务在同一时间运行,例如,在多核处理器上。 并发是独立执行过程的组合,而并行是同时执行(可能相关的)计算。 并发是一次处理很多事情,并行是同时做很多事情。 应用程序可以是并发的,但不是并行的,这意味着它可以同时处理多个任务,但是没有两个任务在同一时刻执行。 应用程序可以是并行的,但不是并发的,这意味着它同时处理多核CPU中的任务的多个子任务。 一个应用程序可以即不是并行的,也不是并发的,这意味着它一次一个地处理所有任务。 应用程序可以即是并行的也是并发的,这意味着它同时在多核CPU中同时处理多个任务。 那么在以往的线程编程中,实现并行的前提就是各个副本可以独立工作,如果在多个副本出现了共享的变量或对象,这就行不通了,因为如果出现同时修改共享变量怎么办 java8的流实现比线程更容易,尽量保持流处理过程中,不访问共享的可变变量,这种函数就被称为纯函数,无副作用函数或无状态函数。但是依旧可以使用sync来实现一个可变数据,但是这样就与并行的概念相悖 函数 方法引用 编写一个目录下查询出所有隐藏文件 @Test public void test() throws Exception { File[] files = new File(".").listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isHidden(); } }); for (File file : files) { System.out.println(file); } } 如上啰里啰嗦的只是判断 pathname.isHidden(),java8引入之前只能这么写,但是现在可以这样 @Test public void test() throws Exception { File[] files = new File(".").listFiles((File::isHidden)); for (File file : files) { System.out.println("file = " + file); } } 上面是将isHidden方法做为值传入listFIles方法,与用对象引用传递对象相似,在java8里写下File::isHidden的时候,就创建了一个方法引用,然后可以传递这个引用了 lambda匿名函数 比如代码(int x ) -> x+1,代码的意思就是你传入一个2,那么他会返回3,也可以像上面定义一个方法add1,然后class::add1,但是对于简短逻辑明确的代码来说这样更简洁,如果匿名函数有很多行代码,不能一眼看出这个匿名函数是干嘛的,那么就应该把匿名函数抽出来一个方法使用 实例 bean代码 @AllArgsConstructor @NoArgsConstructor @Data public class Apple { private String color; private Integer weight; } java8之前:苹果根据条件过滤:找出绿色苹果 @Test public void test() throws Exception { List<Apple> apples = new ArrayList<>(); for (Apple apple : apples) { if ("green".equals(apple.getColor())){ System.out.println(apple); } } } java8之前:苹果根据条件过滤:找出1000克以上的大苹果 @Test public void test() throws Exception { List<Apple> apples = new ArrayList<>(); for (Apple apple : apples) { if (1000 < apple.getWeight()){ //其他代码与上面都是一直的,无奈的是只能复制黏贴改条件,复制黏贴是为限的,因为如果有一天需要改一个地方,如果忘记了另一处复制的代码,那么就会出错 System.out.println(apple); } } } java8之后 改变Apple类 @AllArgsConstructor @NoArgsConstructor @Data public class Apple { private String color; private Integer weight; public static boolean filterWeight(Apple apple){ return 1000 < apple.getWeight(); } public static boolean filterColor(Apple apple){ return "green".equals(apple.getColor()); } } 增加接口 public interface FindApple<T> { boolean find(T t); } 编写方法测试 @Test public void test() throws Exception { List<Apple> apples = new ArrayList<>(); filterApple(apples,Apple::filterColor); //java8之后:苹果根据条件过滤:找出绿色苹果 filterApple(apples,Apple::filterWeight); //java8之后:苹果根据条件过滤:找出1000克以上的大苹果 } static void filterApple(List<Apple> apples,FindApple<Apple> f){ for (Apple apple : apples) { if (f.find(apple)){ System.out.println(apple); } } } 自己实现方法引用确实有点复杂,首先要为需要过滤的类增加自实现的static方法,然后编写带有测试方法的结果,之后就是编写方法,此方法是可以接收需要测试类内static方法的。 如上方法filterApple中的f.find(apple),都是可以看出来这是在使用接口中的测试方法,但是这个方法没有实现自己的逻辑,所以到这它是不能按照要求过滤apple的,然后在上面junit测试方法中,传入的Apple::filterColor其实就是为接口中的测试方法添加逻辑,使其能按照我们的要求过滤apple 从传递方法到lambda 如上自己实现方法引用那真是脸上心里全都是mmp,为了实现方法引用,我们增加类Apple的方法,增加了接口等,如果java8要真是这样,那么宁可不用,不过java8是解决了这个问题的,他引入了lambda表达式,这时候上面的写法就可以写为 将增加的接口删掉~ 将在Apple内增加的方法删掉~ 编写代码 @Test public void test() throws Exception { List<Apple> apples = new ArrayList<>(); filterApple(apples,(apple -> "green".equals(apple.getColor()))); filterApple(apples,(apple -> (apple.getWeight() > 1000))); } static void filterApple(List<Apple> apples, Predicate<Apple> f){ for (Apple apple : apples) { if (f.test(apple)){ System.out.println(apple); } } } 这时候看到的变化是从原来的FindApple接口改变为了Predicate接口,其实这个接口的定义跟刚才的FIndApple接口内定义是一样一样的,如下 @FunctionalInterface public interface Predicate<T> { boolean test(T t); .... .... } 最大的变化就是我们并没有使用方法引用,而是直接以更直观的方法来过滤apple 流 日常写代码的时候,在java8之前如果要遍历Map中找出map对应key的特定value值,如果更加复杂的类型就需要嵌套循环并且编写出来的代码是一大坨的 void test() throws Exception {Map maps = new HashMap<>();for (Map.Entry integerStringEntry : maps.entrySet()) { if (integerStringEntry.getKey() > 1000) { if (integerStringEntry.getValue().equals("value")){ System.out.println("integerStringEntry = " + integerStringEntry); } } } } Stream api就类似SQL一样的过滤操作,如上的代码可以写为下面这样的 void test() throws Exception {Map maps = new HashMap<>();maps.entrySet().stream() .filter(entry -> entry.getKey() > 1000) .filter(entry -> entry.getValue().equals("value")) .forEach(System.out::println); } Stream 解决了经典的java程序只能利用一个cpu的问题,可以使程序并行执行,如图 - 在两个cpu上筛选数据,分割数据到两个cpu上,如1 - 按条件过滤数据,如2 - 一个cpu会将结果汇总起来,如3 Stream顺序处理 maps.entrySet().stream().... Stream的并行处理 maps.entrySet().parallelStream().... 默认方法 如上已经看到了,在java8中使用集合类都会有stream方法,那么在java8之前是没有这个方法,如果把java7升级到java8,那么多的这个stream方法不就的需要实现吗,那么不就不能向后兼容了吗? 如上的问题全是由接口内的默认方法实现的 默认方法的定义是由default开始的,比如 public interface MyFunction { default boolean test(String str) { return str.equals(".."); } } public class UU implements MyFunction{ public static void main(String[] args) { UU uu = new UU(); System.out.println(uu.test("..")); } } 如上UU类中根本不要实现接口中的test方法就可以使用,当然也可以覆盖实现 public class UU implements MyFunction{ @Override public boolean test(String str) { return "ll".equals(str); } public static void main(String[] args) { UU uu = new UU(); System.out.println(uu.test("..")); } } 这时候实现的逻辑就是子类重写之后的了 我们都知道接口是可以多重实现的,那么如果IA和IB中方法名重复了咋办 public interface MyFunction1 { default boolean test(String str) { return str.equals(".."); } } public interface MyFunction2 { default boolean test(String str) { return str.equals("ll"); } } public class UU implements MyFunction1,MyFunction2{ //exception public static void main(String[] args) { UU uu = new UU(); System.out.println(uu.test("..")); } } 如上当两个接口中的方法名重复了,那么就会出错,解决办法就是重写重复的方法即可,当然方法重载是没有问题的 这就是为什么在更新为java8之后,之前的代码还是可以使用的原因,java8 在Collection接口中加入了stream默认实现了 default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); }

优秀的个人博客,低调大师

17.Swift学习之类

类介绍 Swift虽然推荐面向协议编程,但其也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象(类的实例) Swift中用class关键字定义类 定义语法 class 类名 { // 定义属性和方法 } 举例 class Person { var name = "Zhangsan" var age = 10 var sex = "man" func say(){ print("人会说话") } } 解读 定义了一个名叫 Person的类 这个类有三个变量存储属性和一个方法 类的实例 结构体一样,最简单的是在名称后面加一个(),但默认没有成员构造函数 var p1 = Person() 访问属性和方法 可以用.来访问一个实例的属性和方法 访问时如果使用了赋值语句就是设置属性 //普通构造函数 var p1 = Person() //访问 p1.age //设置 p1.age = 30 p1.name p1.sex p1.say() 类是引用类型 不同于值类型,引用类型被赋值到一个常量,变量或者本身被传递到一个函数的时候它是不会被拷贝的,而使用的是同一个对某个实例的引用。 var p2 = p1 p2.name = "Lisi" p2.age = 20 p2.sex = "woman" //对p2的修改会影响原来的p1 p1.age p1.name p1.sex 特征运算符 因为类是引用类型,可能有很多常量和变量都是引用到了同一个类的实例。有时候需要找出两个常量或者变量是否引用自同一个实例,Swift提供了两个特征运算符来检查两个常量或者变量是否引用相同的实例。 相同于 ( ===) 不同于( !==) //特征运算符 let p3 = Person() p1 === p2 //true p1 === p3 //false p1 !== p3 //true 继承 一个类可以从另一个类继承方法、属性和其他的特性 当一个类从另一个类继承的时,继承的类就是子类,被继承的就是父类 继承的目的是为了代码复用 Do Not Repeat Yourself 案例 // 定义一个父类 class Vehicle { var currentSpeed = 0.0 func makeNoise() { print("Ba Ba") } } // 定义一个子类 class Bicycle: Vehicle { var hasBasket = false } // 定义一个子类 class Car: Vehicle { var banner = "皖B12345" } var vehicle = Vehicle() vehicle.makeNoise() let bicycle = Bicycle() bicycle.makeNoise() var car = Car() car.makeNoise() 重写(覆写) 所谓重写就是子类可以对继承自父类实例方法、类型方法、实例属性,类型属性进行覆盖 重写需要在前面加上 override 关键字 override 关键字执行时Swift 编译器会检查重写的类的父类(或者父类的父类)是否有与之匹配的声明来提供重写 class Car: Vehicle { var banner = "皖B12345" override func makeNoise() { print("Di Di") } } var car = Car() car.makeNoise() 防止被重写 可以通过final标记阻止这种行为:final var , final func , final class func class Vehicle { var currentSpeed = 0.0 func makeNoise() { print("Ba Ba") } //不能被子类重写 final func run() { print("Run Run") } } 类与结构体的对比 相同点 定义属性 定义方法 定义构造函数(init函数) 可以被扩展 遵循协议 类有而结构体没有的额外功能 继承 类型转换(子类 as 父类) 析构函数 引用计数 开发中类与结构体的使用场景 类和结构体都可以用来定义自定义的数据类型,结构体实例总是通过值来传递,而类实例总是通过引用来传递。 按照通用准则,当符合以下一条或多条情形时应考虑结构体,其他情况下,使用类。大部分的自定义的数据结构应该是类,而不是结构体。 要描述的数据类型中只有少量的简单数据类型的属性 要描述的数据类型在数据传递时要以复制的方式进行 要描述的数据类型中所有的属性在进行传递时需要以复制的方式进行 不需要继承另一个数据类型 比如: 定义几何形状的大小,封装了一个 width属性和 height属性,两者为 Double类型; 定义一定范围的路径,封装了一个 start属性和 length属性,两者为 Int类型; 定义三维坐标系的一个点,封装了 x , y 和 z属性,它们是 Double类型。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册