java入门第一阶段
1.在java中接受并保存用户输入的值:
(1)import java.util.Scanner//引入包 (2)Scanner input=new Scanner (System.in);//创建Scanner对象 (3)int score=input.nextInt();//获取用户输入的信息并规定了变量的类型(这里是int)
2.在java中对数组的基本操作:
(1)import java.util.Arrays;//引入包 (2) // 使用Arrays类的sort()方法对数组进行排序 Arrays.sort(scores); // 使用Arrays类的toString()方法将数组转换为字符串并输出 Arrays.toString(scores);
3.使用foreach基本操作:
(1) int[] scores = { 89, 72, 64, 58, 93 }; for ( int score:scores) {//定义数组中的元素名称为score System.out.println(score); }
4.定义java中的方法:
(1)无参无返回值: public void calcAvg() { ...... } (2)无参带返回值: public double calcAvg() { ...... return (double型的数据) } (3)带参无返回值: public static void main(String[] args) { // 创建对象,对象名为hello HelloWorld hello = new HelloWorld(); // 调用方法,传入两门课程的成绩 hello.calcAvg(94, 81); } public void calcAvg(int a,int b){ float avg=(a+b)/2; System.out.println("平均分:"+avg); } (4)带参带返回值: public static void main(String[] args) { HelloWorld hello = new HelloWorld(); int[] scores={79,52,98,81}; //调用方法,传入成绩数组,并获取成绩的个数 int count=hello.sort(scores); System.out.println("共有"+count+"个成绩信息!"); } public int sort( int scores[] ){ Arrays.sort(scores); System.out.println(Arrays.toString(scores)); //返回数组中元素的个数 return scores.length; }
5.方法的重载
如果同一个类中包含了两个或两个以上方法名相同、方法参数的个数、顺序或类型不同的方法,则称为方法的重载,也可称该方法被重载了。 public static void main(String[] args) { // 创建对象 HelloWorld hello = new HelloWorld(); // 调用无参的方法 hello.print(); // 调用带有一个字符串参数的方法 hello.print("print"); // 调用带有一个整型参数的方法 hello.print(1); } public void print() { System.out.println("无参的print方法"); } public void print(String name) { System.out.println("带有一个字符串参数的print方法,参数值为:" + name); } public void print(int age) { System.out.println("带有一个整型参数的print方法,参数值为:" + age); }
6.类和对象
(1)类相当于模子,确定对象将会拥有的特征(属性)和行为(方法) (2)手机就是类,华为P30pro就是对象 例子:package test1; import java.util.Arrays; public class helloWorld{ int a,b,c; public static void main(String[] args) { ...... } public void sort(int a[]){ ...... }
}
7.成员变量和局部变量
(1) 成员变量作用域---类 局部变量作用域---定义的方法 (2) 成员变量有初始值为0,局部没有。如果不定义成员变量不报错,局部变量报错。 (3) 不同方法中可以有相同名称的局部变量。 (4) 成员变量和局部变量可以重名,方法默认调用局部变量的值。
8.构造方法
(1)用来初始化对象的方法。和类名相同且没有返回值 (2)helloWorld类中创建对象 helloWorld test=new helloWorld();//无参的方式创造对象 helloWorld test=new helloWorld(1,2,3);//有参的方式创造对象,对对象赋初值。 (3)可以在同一个类中创建几个构造方法,名字都得和类相同,不同在于有无参数,参数的个数类型不同。可以在构造参数中对传参的值进行判断如果不合理则赋予默认值。 (4)当没有指定构造方法时,系统自动添加无参的构造方法,如果有指定构造方法时,不会自动添加(意思就是说你在类里没有写和类同名的方法,系统就自动写一个,写了和类同名的方法,系统就不会再写了)
9.静态变量和静态方法
==静态方法调用静态变量,不能调用成员变量==
(1)静态变量和静态方法都是属于类中的,不属于对象中,比如创建一个对象,可以用类.静态方法来调用该方法,对于类创建的任何对象都能用,所以不安全或者说可以用来做公共的方法。 (就像在PHP开发中为了方便,可以将共用功能的类或者方法放在同一个层控制层或者服务层需要用这种方法时只需要引入类再调用类中的方法,也可以再重构这种方法,变成自己功能块中需要的方法) (2)静态方法不能直接访问成员变量:成员变量必需实例化之后才能被用,而静态方法不用被实例化,只要写了这个类和这个方法就能被用上。 (换句话说,成员变量属于非静态的东西,而程序在加载中先加载静态的东西,不会变得东西,然后再加载非静态的,如果静态方法调用了非静态的东西这样就会陷入死循环)
10.封装,继承,多态
equals一般可以通过重写判断特定类的属性值是否相同。==主要可以用于基本数据类型和引用数据类型,在基本数据类型中主要用来判断数据的值,引用数据类型主要判断引用数据的地址值是否相同
注意:java中包命名全是小写字母,可以引入某个包下所有文件如:import com.myerebos.*,一般来说会以一个项目名称倒写来做包名,如myerebos.com项目的包名为com.myerebos 访问控制符private,默认,protect,public的范围分别是:本类,本包,本包和子类,无范围。 (1) 封装:将类的某些信息(写的某些方法,变量)隐藏在类的内部,不允许外 部程序直接访问,只能通过调用类中的方法来对信息进行操作和访问(好 处在于通过规定的方法访问数据,隐藏细节方便修改和实现) 可以通过定义访问控制符来改写,如:private,创建getter和setter方法,在方法中加入属性控制语句。(这样就不能直接用调用修改类中的参 数) (2) 继承:extends,父类子类关系,子类继承父类方法,属性(要看访问控制符,被private修饰的不能被访问),可以重写父类的方法。子类对象在初始化后会自动的!!!先建立父类对象的属性,然后是父类对象的构造方法,再是子类对象的属性,最后才是子类对象的构造方法。 注意:final关键字:修饰的类,方法,属性,变量(都不可变且不能被继承,意思就是最终形态了) this关键字:调用本类中的属性或者方法 super关键字:调用父类中的属性或者方法(子类想调用父类构造方法的时候必需得先在构造方法第一行声明super();) 所有子类都继承Object类(java类的老祖宗),如果不重写tostring(),子类调用tostring()会直接输出该子类的地址(哈希值)。 (3) 多态:在实例化类的对象的时候父类可以直接实例化子类对象,这样就可以调用子类中的方法了,但是子类不能实例化父类对象。如:Animal obj=new Dog(); obj.test();(这里的test方法是dog类中定义的) 如果是子类特有的方法,那这种方式就不能调用。 注意:强制类型转换Dog dog =(Dog)animal(类似于属性的强制转换,小转大有风险。int强制转换成double没问题,double转换成int会有四个数位丢失) instanceof用于判断类的类型,如:animal instanceof Cat 盘点Cat是否是animal类
11.内部类
内部类的主要作用如下: 1. 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类 2. 内部类的方法可以直接访问外部类的所有数据,包括私有的数据 3. 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便 内部类可分为以下几种: (1)成员内部类:可以调用外部类中定义的变量,不受访问控制符public,private,protect的影响。(成员内部类相当于外部类的一个成员 变量)定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象如: Outer o=new Outer();//先定义外部类 Inner i=o.new Inner();//定义内部类 i.test();//调用内部类的方法 注意: 外部类是不能直接使用内部类的成员和方法,要访问要先创建内部类对象,如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字,如: public class HelloWorld{ //外部类的私有属性name private String name = "imooc"; int age = 20; //成员内部类Inner public class Inner { String name = "爱慕课"; //内部类中的方法 public void show() { System.out.println("外部类中的name:" + HelloWorld.this.name); System.out.println("内部类中的name:" + name ); System.out.println("外部类中的age:" + age); } } } (2)静态内部类: 1、 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问 2、如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员。 System.out.println("访问外部类中的score:"+ HelloWorld.score); System.out.println("访问内部类中的score:" + score); 3、在外部类或者内部类中药实例化一个静态内部类对象如果不需要外部类的对象,可以直接创建。SInner si=new SInner(); (3)方法内部类:方法内部类就是内部类定义在外部类的方法中,只能在方法内部使用。 (4)匿名内部类 例子:public class HelloWorld { // 内部类Inner,类Inner在类HelloWorld的内部 public class Inner { // 内部类的方法 public void show() { System.out.println("welcome to imooc!"); } } public static void main(String[] args) { // 创建外部类对象 HelloWorld hello = new HelloWorld(); // 创建内部类对象 Inner i = hello.new Inner(); // 调用内部类对象的方法 i.show(); } }
12. 抽象类
可以相当于一个类的模板,限定类必须要有什么样的方法,属性。但是具体的值或者方法如何编写不清楚。一般继承的子类重写方法或者属性。( 相当于PHP项目在写验证层,异常层这样的代码时会先做一个基类,然后层里其他的类会继承这个类,在这个类的基础上重写方法属性) 如:package test1; public abstract class HelloWorld { public abstract void hello(); public abstract void World(int a); }//抽象方法一定没有方法体{},以;结尾,所以必须是void无返回值。
13. 接口
用interface定义,一般用于被继承和被实现所以一般用public,接口的内容是常量(public static final)和抽象方法(public abstract), 可以继承多个父接口(多继承),用implement实现接口 如: public abstract interface ISay {//声明接口 public abstract void sayhello(); } public class HelloWorld extends Object implements ISay {//继承类,实现接口 public void hello(){ System.out.println("..."); }; public void sayhello(){//实现接口中的方法 System.out.println("hello"); } ISay s1=new HelloWorld(); } 接口可以配合匿名内部类使用。
14. 字符串
一旦一个字符串在内存中创建,则这个字符串将不可改变。如果需要一个可以改变的字符串,我们可以使用StringBuffer或者StringBuilder。 string s1="ddsd"; s1=s1+"sdak";//这里的s1相当于在内存中开辟了新的字符串对象。 String s1 = "imooc"; String s2 ="imooc";//s1和s2在内存中创建的同一个对象,imooc为常量字符串,多次出现时会被编译器优化,只创建一个对象 ==: 判断两个字符串在内存中首地址是否相同,即判断是否是同一个字符串对象 equals(): 比较存储在两个字符串对象中的内容是否一致 常用的字符串方法:String str="......" int a=str.length();//字符串长度 int b=str.indexOf('a');//字符位置 String z=s.replace('i','o');//替换字符 int b2=str.lastIndexOf('a');//该字符最后一次出现的位置 int c=str.indexOf('JAVA');//字符串位置 String[] arr=str.split(",");//按,把字符串拆分成数组 String s=str.substring(3,7);//获取索引在[3,7)之间的子字符串 String s1=str.trim();//除去字符中的空格 s.equals(s2);//比较两个字符串的值 String s2=s.toLowerCase();//变成小写 String s3=s.toUpperCase();//变成大写 char c1=s.charAt(i);//查询字符串指定位置字符 byte[] b2=s.getBytes();//字符串转换为byte数组
15. StringBuilder和StringBuffer
(1)StringBuilder: String str="hello"; System.out.println(str+"world"); System.out.println(str);//这样的话 程序运行时会额外创建一个对象,保存"helloworld"。当频繁操作字符串时,就会额外产生很多临时变量。使用 StringBuilder 或 StringBuffer 就可以避免这个问题。至于 StringBuilder 和StringBuffer ,它们基本相似,不同之处,StringBuffer 是线程安全的,而 StringBuilder则没有实现线程安全功能,所以性能略高。因此一般情况下,如果需要创建一个内容可变的字符串对象,应优先考虑使用 StringBuilder 类。 例: // 创建一个空的StringBuilder对象 StringBuilder str=new StringBuilder(); // 追加字符串 str.append("jaewkjldfxmopzdm"); str.insert(1,'s');//在特定位置插入 String str1=str.toString();//将StringBuilder类转换为String类 (2)StringBuffer:在应用程序要求线程安全的情况下,则必须使用 StringBuffer类。 public StringBuffer append(Strings) //将指定的字符串追加到此字符序列 public StringBuffer reverse() //将此字符序列用其反转形式取代。 public delete(int start, int end) //移除此序列的子字符串中的字符。 public insert(int offset, int i) //将int参数的字符串表示形式插入此序列中。 replace(int start, int end, String str) //使用给定 String 中的字符替换此序列的子字符串中的字符。
16.包装类
为了让基本数据类型(例如 int、float、double、boolean、char 等)也具备对象的特性,Java为每个基本数据类型都提供了一个包装类,这样我们就可以像操作对象那样来操作基本数据类型。如: public class HelloWorld { public static void main(String[] args) { // 定义int类型变量,值为86 int score1 = 86; // 创建Integer包装类对象,表示变量score1的值 Integer score2=new Integer(score1); // 将Integer包装类转换为double类型 double score3=score2.doubleValue(); // 将Integer包装类转换为float类型 float score4=score2.floatValue(); // 将Integer包装类转换为int类型 int score5 =score2.intValue(); System.out.println("Integer包装类:" + score2); System.out.println("double类型:" + score3); System.out.println("float类型:" + score4); System.out.println("int类型:" + score5); } } 基本类型和包装类的相互转换:自动装箱,手动装箱,自动拆箱,手动拆箱; // 定义double类型变量 double a = 91.5; // 手动装箱 Double b =new Double(a); // 自动装箱 Double c = a; System.out.println("装箱后的结果为:" + b + "和" + c); // 定义一个Double包装类对象,值为8 Double d = new Double(87.0); // 手动拆箱 double e = d.doubleValue(); // 自动拆箱 double f = d; // 将字符串转换为基本类型 Double a =Double.valueOf(str); //将基本类型转换为字符串 String str1 = String.valueOf(m);
17.Date类,SimpleDateFormat类,Calendar类
// 使用format()方法将日期转换为指定格式的文本 SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); // 创建Date对象,表示当前时间 Date now=new Date(); // 调用format()方法,将日期转换为字符串并输出 System.out.println(sdf1.format(now)); // 调用parse()方法,将字符串转换为日期 String d = "2014-6-1 21:05:36"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse(d); System.out.println(date); java.util.Calendar 类是一个抽象类,可以通过调用 getInstance() 静态方法获取一个Calendar对象,此对象已由当前日期时间初始化,即默认代表当前时间。 如 Calendar c = Calendar.getInstance(); // 将Calendar对象转换为Date对象 Date date = c.getTime(); int year=c.get(Calendar.YEAR);//获取年 // 创建SimpleDateFormat对象,指定目标格式 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 将日期转换为指定格式的字符串 String now = sdf.format(date); System.out.println("当前时间:" + now);
18. Math类
Math.round(3.5);//返回四舍五入的整数 Math.floor(4.2);//返回小于参数的最大整数 Math.ceil(1.2);//返回大于参数的最小整数 Math.random();//返回随机数(0,1)
19. 异常
==当Java内置的异常都不能明确的说明异常情况的时候,需要创建自己的异常。==
==捕捉并处理知道如何处理的异常,而抛出不知道如何处理的异常。==
Throwable: (1)Error (2)Exception 1)IOException(可查异常(编译器要求必须处置的异常)) 2)RuntimeException(不可查异常(编译器不要求强制处置的异常)) 1. 错误:对于方法运行中可能出现的Error,当运行方法不欲捕捉时,Java允许该方法不做任何抛出声明。因为,大多数Error异常属于永远不能被允许发生的状况,也属于合理的应用程序不该捕捉的异常。 2. 运行时异常:由于运行时异常的不可查性,为了更合理、更容易地实现应用程序,Java规定,运行时异常将由Java运行时系统自动抛出,允许应用程序忽略运行时异常。 3. 可查异常:对于所有的可查异常,Java规定:一个方法必须捕捉,或者声明抛出方法之外。也就是说,当一个方法选择不捕捉可查异常时,它必须声明将抛出异常。(对于可查异常必须捕捉、或者声明抛出。允许忽略不可查的RuntimeException和Error。) 捕获异常的格式:捕获的异常必须是先小后大,子类异常在父类异常前面 Scanner input=new Scanner(System.in); try{ System.out.println("输入第一段"); int one=input.nextInt(); System.out.println("输入第二段"); int two=input.nextInt(); System.out.println("相除"+one/two); }catch (InputMismatchException e){ System.out.println("输入整数"); }catch (ArithmeticException e){ System.out.println("不能除以0"); }catch (Exception e){ System.out.println("不知名异常"); }finally{ //最终还会输出的语句,finally可写可不写了,写了的话任何情况都会执行这条语句 } System.out.println("程序结束"); 抛出异常的格式: public void add(int index, E element){ if(size >= elements.length) { throw new RuntimeException("顺序表已满,无法添加"); //return; //需要吗? } .... }
注意:
1.常用的数组类的方法Array.toString();Array.sort();Array.binarySearch();
2.在Integer类中== (看是否是同一个对象)和equals();方法(看对象的值是否相同),如果取值在byte范围内127到-128,不会创造新的对象而是从常量池中获取,如果超过了则创造新对象。
例:Integer i1=32; Integer i3=129; Integer i2=32; Integer i4=129; i1\==\i2为true; i3\==\i4为flase; i1.equals(i2);为true i3.equals(i4);为true
3.public class HelloWorld {
private String sss;
public HelloWorld(){
super();//创建一个类之后,要在构造方法中调用super,否则父类相关字段就不会被初始化
};
}
20. 集合
集合类似于数组,但是数组是静态的,一个数组实例具有固定的大小,一旦创建了就无法改变容量了。而集合是可以动态扩展容量,可以根据需要动态改变大小。数组可以储存基本类型和引用数据类型,集合只能储存引用数据类型( 对象) 注意: 1.List类中add()方法永远返回true(因为可以存储重复元素,这一点和set完全相反) 2.Collection集合中用的最多的是ArrayList类(如果元素是不唯一,用),其次是HashSet类(元素唯一,用) 3.Map集合中HashMap用的最多其次是TreeMap (1)Collection 1)List(有序,有索引,存储可以重复,和数组类似) -ArrayList(数组实现,一般用这个) -LinkedList(链表实现,增删多用这个) -vector(很早的,List的前身,数组实现) 2)Queue 3)Set(无序,无索引,不可以存储重复) -HashSet(哈希表实现) -TreeSet(红黑树(二叉树)实现) (2)Map 1)Hashtable(同步,无序,效率低,线程安全) 2)LinkedHashMap(按FIFO顺序存储) 3)HashMap(不同步,无序,效率高,线程不安全) 4)TreeMap(有序,先排列好再储存,效率低) Hashtable不允许null值,HashMap允许null值
21. ArrayList类和LinkList类
注意:add,contains,remove,retain(取交集) 都可以+all表示对集合的操作 ArrayList c = new ArrayList();//父类引用指向子类对象 ArrayList c1 = new ArrayList(); c.add("123");//添加任意类型的数据存入ArrayList对象 c.add(1); Student s=new Student("Tom",18,'男'); Student s1=new Student("jim",30,'男'); c.add(s); c1.add(s1); System.out.println(c); System.out.println(c.contains(s));//判断s是否是c中的存在的对象 System.out.println(c.get(2));//获取c中的第三个对象,如果索引越界会报错。 System.out.println(c.indexOf(s));//获取c中s对象的索引,如果不是c中的对象,哪怕值一样也是-1 System.out.println(c.remove("123"));//删除c中的s对象,可以直接写对象也可以写索引。 System.out.println(c.set(0,s1));//将c中下标为2的对象替换成s2 System.out.println(c.size());//集合c的长度 System.out.println(c.addAll(c1));//将c1中的元素加到c中 c.clear();//清空c中的元素 Object[] arr=c.toArray();//集合先会转换成Object类型的数组,可以通过循环遍历,然后再将object数组中的元素强行转换成想要的元素类型 for(int i=0;i<arr.length;i++){ Student s=(Student)arr[i]; } //迭代器也是增强型的for循环的底层(foreach) Iterator it = c.iterator();//获取迭代器,就是用来遍历 boolean b1=it.hasNext();//确定集合中是否有元素,有就返回true while (it.hasNext()){ System.out.println(it.next());//类似每次取一位,指针向后移一位。 } while(it.hasprevious()){//指针每次向前移动一位,逆向输出 System.out.println(it.previous()); } /* LinkedList中的特有的方法*/ LinkedList l=new LinkedList(); l.addFirst("a");//每次都添加到第一位 l.addFirst("b"); l.addFirst("c"); System.out.println(l.getFirst());//获取第一位元素 System.out.println(l.getLast());//获取最后一位元素 System.out.println(l.removeLast());//除去最后一位元素 System.out.println(l.removeFirst());//除去第一位元素
例子:封装一个类用做其他类的功能块
public class Stack { private LinkedList list=new LinkedList(); public void in(Object obj){ list.addLast(obj); } public Object out(){ return list.getFirst(); } }
22.泛型(Generic)
好处在于1.编译时强类型检查;2.无需手动进行类型转换;3.可以实现复用,编写通用算法 注意:类,方法,接口也能声明泛型,表示该类该方法只能传入这种类型的参数 ArrayList<Stack> s=new ArrayList<Stack>();//声明该集合对象只能存入Stack类的对象元素 Stack n=new Stack("xu"); s.add(n); //s.add(12);//编译时强类型检查;
注意:
1. 迭代器,for循环,增强for循环(三种循环中只有增强for循环不能被用来删除) 2. 可变参数方法: public static void print(char...arr){//可变参数,输入的参数个数可以随便改 for (int i=0;i<arr.length;i++){ System.out.println(arr[i]); } } 3. Arrays中的asList()方法 String [] arr={"ss","bb","dd"}; List<String> s= Arrays.asList(arr);//数组转换成集合,基本数据类型转换成集合,会将整个数组当成一个对象 4.集合的嵌套 ArrayList<ArrayList <Stack>>s=new ArrayList<>(); ArrayList<Stack>S1=new ArrayList<>(); ArrayList<Stack>S2=new ArrayList<>(); S1.add(new Stack("XU")); S1.add(new Stack("GG")); S2.add(new Stack("MU")); s.add(S1); s.add(S2); for (ArrayList<Stack> i:s) { for (Stack name:i){ System.out.println(name); } }
23. HashSet类
Set集合的方法和collection方法一样,只是效果略不同 HashSet存储自定义对象必须要,重写HashCode方法,才能保证元素唯一