Java优秀教程
1、java中局部变量是在栈上分配的;
2、数组是储存在堆上的对象,可以保存多个同类型变量;
3、在Java语言中,所有的变量在使用前必须声明。
4、局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。
5、内置类型有默认值,引用对象的默认值是null;
6、非静态实例变量、非静态方法是通过对象实例进行调用的,不能直接从静态方法中调用;比如java源文件中main方法中不可以直接调用非静态方法;
7、静态变量、实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。
8、在构造方法中,当实例变量的名称跟局部变量的名称一致时,实例变量的使用就要用this了。
9、静态变量(类变量)除了被声明为常量外很少使用。常量是指声明为public/private,final和static类型的变量。常量初始化后不可改变。
10、静态变量储存在静态存储区。经常被声明为常量,很少单独使用static声明变量。
11、类变量被声明为public static final类型时,类变量名称一般建议使用大写字母。如果静态变量不是public和final类型,其命名方式与实例变量以及局部变量的命名方式一致。
12、方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
13、类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
14、 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
15、String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了。如果需要对字符串做很多修改,那么应该选择使用 StringBuffer & StringBuilder 类。
16、Java 语言中提供的数组是用来存储固定大小的同类型元素。
17、java遍历二维数组:
-
package com.example.test;
-
-
-
import java.io.*;
-
public class EmployeeTest{
-
-
public static void main(String[] args){
-
String s[][]=new String[2][];
-
s[0]=new String[2];
-
s[1]=new String[3];
-
s[0][0]=new String("Good");
-
s[0][1]=new String("Luck");
-
s[1][0] = new String("to");
-
s[1][1] = new String("you");
-
s[1][2] = new String("!");
-
System.out.println(s.length);
-
for(int a=0;a<s.length;a++) {
-
for(int i=0;i<s[a].length;i++) {
-
System.out.print(s[a][i]+" ");
-
}
-
System.out.println();
-
}
-
}
-
}
运行结果:
18、休眠三秒:
-
try {
-
System.out.println(new Date()+"\n");
-
Thread.sleep(1000*3);// // 休眠3秒
-
System.out.println(new Date()+"\n");
-
}catch(Exception e) {
-
System.out.println("Got an exception!");
-
}
运行结果:
19、计算日期间隔:
-
try {
-
long start = System.currentTimeMillis( );
-
System.out.println(new Date( ) + "\n");
-
Thread.sleep(5*60*10);
-
System.out.println(new Date( ) + "\n");
-
long end = System.currentTimeMillis( );
-
long diff = end - start;
-
System.out.println("Difference is : " + diff);
-
} catch (Exception e) {
-
System.out.println("Got an exception!");
-
}
运行结果:
20、从控制台读取数据
带reader的是字符流
// 使用 BufferedReader 在控制台读取字符
// 使用 System.in 创建 BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
从控制台读取字符串
str = br.readLine();
从控制台读取多字符输入
c = (char) br.read();
21、控制台输出
PrintStream 继承了 OutputStream类,并且实现了方法 write()。这样,write() 也可以用来往控制台写操作。
-
int b;
-
b = 'A';
-
System.out.write(b);
-
System.out.write('\n');
注意:write() 方法不经常使用,因为 print() 和 println() 方法用起来更为方便。
22、读写文件
字节流写文件易出现乱码(字节流是二进制)
不使用字节流专用字符流:
-
package com.example.test;
-
-
-
import java.io.*;
-
import java.text.SimpleDateFormat;
-
import java.util.Calendar;
-
import java.util.Date;
-
import java.util.Scanner;
-
public class EmployeeTest{
-
-
public static void main(String[] args) throws IOException{
-
File f = new File("a.txt");
-
FileOutputStream fop = new FileOutputStream(f);//字节流输出流
-
// 构建FileOutputStream对象,文件不存在会自动新建
-
-
OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");//字符流写文件
-
// 构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk
-
-
writer.append("中文输入");
-
// 写入到缓冲区
-
-
writer.append("\r\n");
-
//换行
-
-
writer.append("English");
-
// 刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入
-
-
writer.close();
-
//关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉
-
-
fop.close();
-
// 关闭输出流,释放系统资源
-
-
FileInputStream fip = new FileInputStream(f);//字节流
-
// 构建FileInputStream对象
-
-
InputStreamReader reader = new InputStreamReader(fip, "UTF-8");//字符流
-
// 构建InputStreamReader对象,编码与写入相同
-
-
StringBuffer sb = new StringBuffer();
-
while (reader.ready()) {//判断此流是否已准备好被读取,是一个非阻塞的方法,所以会立刻返回,由于服务器没有准备好被读,所以会立刻返回,所以读取到的都是null
-
sb.append((char) reader.read());
-
// 转成char加到StringBuffer对象中
-
}
-
System.out.println(sb.toString());
-
reader.close();
-
// 关闭读取流
-
-
fip.close();
-
// 关闭输入流,释放系统资源
-
-
}
-
-
-
}
23、重写
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
尽管对象引用b属于Animal类型,但是它运行的是Dog类的move方法。
这是由于在编译阶段,只是检查参数的引用类型。
然而在运行时,Java虚拟机(JVM)指定对象的类型并且运行该对象的方法。
因此在上面的例子中,之所以能编译成功,是因为Animal类中存在move方法,然而运行时,运行的是特定对象的方法。
24、方法的重写规则
参数列表必须完全与被重写方法的相同;
返回类型必须完全与被重写方法的返回类型相同;
访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
父类的成员方法只能被它的子类重写。
声明为final的方法不能被重写。
声明为static的方法不能被重写,但是能够被再次声明。
子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
构造方法不能被重写。
如果不能继承一个方法,则不能重写这个方法。
25、重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
26、方法的重载规则:
被重载的方法必须改变参数列表(参数个数或类型不一样);
被重载的方法可以改变返回类型;
被重载的方法可以改变访问修饰符;
被重载的方法可以声明新的或更广的检查异常;
方法能够在同一个类中或者在一个子类中被重载。
无法以返回值类型作为重载函数的区分标准。
27、重载和重写的区别:
28、重写+重载=总结
总结
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
(1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
(2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
(3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
29、多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作
多态性是对象多种表现形式的体现。
多态的优点
1. 消除类型之间的耦合关系
2. 可替换性
3. 可扩充性
4. 接口性
5. 灵活性
6. 简化性
多态存在的三个必要条件
继承
重写
父类引用指向子类对象 比如:Animal ad=new Dog();
30、虚方法
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
实例中,实例化了两个 Salary 对象:一个使用 Salary 引用 s,另一个使用 Employee 引用 e。
当调用 s.mailCheck() 时,编译器在编译时会在 Salary 类中找到 mailCheck(),执行过程 JVM 就调用 Salary 类的 mailCheck()。
因为 e 是 Employee 的引用,所以调用 e 的 mailCheck() 方法时,编译器会去 Employee 类查找 mailCheck() 方法 。
在编译的时候,编译器使用 Employee 类中的 mailCheck() 方法验证该语句, 但是在运行的时候,Java虚拟机(JVM)调用的是 Salary 类中的 mailCheck() 方法。
31、虚方法出现在Java的多态特性中
Java虚方法你可以理解为java里所有被overriding的方法都是virtual的,所有重写的方法都是override的。
在JVM字节码执行引擎中,方法调用会使用invokevirtual字节码指令来调用所有的虚方法。
需要注意虚方法和抽象方法并不是同一个概念
32、多态的实现方式
方式一:重写:
这个内容已经在上一章节详细讲过,就不再阐述,详细可访问:Java 重写(Override)与重载(Overload)。
方式二:接口
1. 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。
2. java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体可以看 java接口 这一章节的内容。
方式三:抽象类和抽象方法
33、java抽象类
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。
1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
4. 构造方法,类方法(用static修饰的方法)不能声明为抽象方法。
5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
34、继承:
java继承中对构造函数是不继承的,只是调用(隐式或显式)。
在创建子类的对象时,Java虚拟机首先执行父类的构造方法,然后再执行子类的构造方法。在多级继承的情况下,将从继承树的最上层的父类开始,依次执行各个类的构造方法,这可以保证子类对象从所有直接或间接父类中继承的实例变量都被正确地初始化。
创建有参构造函数后,系统就不再有默认无参构造函数。
如果没有任何构造函数,系统会默认有一个无参构造函数。
35、抽象类和接口的区别:
抽象类中:
可以有构造方法;
方法可以是隐式抽象的;也可以是实现了的方法体;
成员变量可以是各种类型的;
抽象类是可以有静态代码块和静态方法;不能有声明为static的抽象方法;
构造方法,类方法(用static修饰的方法)不能声明为抽象方法。
原因:Java抽象类中不能有静态的抽象方法,可以有静态的成员方法。抽象类是不能实例化的,即不能被分配内存;而static修饰的方法在类实例化之前就已经别分配了内存,这样一来矛盾就出现了:抽象类不能被分配内存,而static方法必须被分配内存。所以抽象类中不能有静态的抽象方法。定义抽象方法的目的是重写此方法,但如果定义成静态方法就不能被重写。
接口中:
不能有构造方法;
方法声明都是隐式抽象的public abstract方法;
接口中的成员变量只能是 public static final 类型的;
接口中不能含有静态代码块以及静态方法(用 static 修饰的方法)
接口中的方法也只能是 public abstract修饰的,不能加上static。接口是不能实例化的,即不能被分配内存,而static修饰的方法在类实例化之前就已经别分配了内存,这样一来矛盾就出现了:接口不能被分配内存,而static方法必须被分配内存。所以接口中不能有静态的抽象方法。
36、接口
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
接口没有构造方法,因为接口不能实例化;
37、集合与泛型
第一:集合框架常用的接口有哪些?
复杂方式存储对象是值键值映射的时候;
java集合框架就是提供一些接口和类,位于java.util包中;
Iterator(操作集合的迭代器)、Map、Collection是接口;虚线空心箭头是子接口继承父接口;长方形实现是实现类;
utilties是工具类:有Collections、Arrays;看见util就是工具类;
第二:这些接口有哪些特点?
Collection接口存储一组不唯一、无序的对象。
List接口存储一组不唯一(可重复)、有序(存储空间连续)(插入顺序)的对象;
Set接口存储一组唯一,无序的对象
Map接口存储一组键值对象,提供key到value的映射;
37.2、ArrayList(是一个可变数组)
ArrayList是连续的空间,长度可变;
LinkedList是可不连续的空间;
shift+alt+s:生成getter和setter
ctrl+shift+o或者Ctrl+1导包;
集合有了list以后,在内存中就开辟空间了;
ArrayList有个固定的长度,插入数据超过后,会自动扩充;
-
package com.example.test;
-
-
public class NewTitle {
-
private int id;
-
private String newsName;
-
private String creater;
-
public NewTitle() {}
-
public NewTitle(int id ,String newsName,String creater) {
-
this.id=id;
-
this.newsName=newsName;
-
this.creater=creater;
-
}
-
public int getId() {
-
return id;
-
}
-
public void setId(int id) {
-
this.id = id;
-
}
-
public String getNewsName() {
-
return newsName;
-
}
-
public void setNewsName(String newsName) {
-
this.newsName = newsName;
-
}
-
public String getCreater() {
-
return creater;
-
}
-
public void setCreater(String creater) {
-
this.creater = creater;
-
}
-
-
-
-
-
-
}
-
package com.example.test;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
-
public class ArrayListDemo {
-
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
NewTitle news1=new NewTitle(1,"title1","admin");
-
NewTitle news2=new NewTitle(2,"title2","admin");
-
NewTitle news3=new NewTitle(3,"title3","admin");
-
-
ArrayList list=new ArrayList();
-
//List list=new ArrayList();//这种接口是向上转移,面向接口编程的时候经常用
-
list.add(news1);
-
list.add(news2);
-
list.add(news3);
-
-
int nums=list.size();
-
System.out.println("共有"+nums+"条标题");
-
System.out.println("*******************");
-
for(int i=0;i<nums;i++) {
-
NewTitle newsTitle=(NewTitle) list.get(i);//找到对应位置上的元素;即:Object
-
System.out.println(newsTitle.getNewsName());
-
}
-
}
-
-
}
运行结果:
标红色的是Collection接口的方法;
clear()是清空集合;isEmpty()返回是True代表清空了;iterator()返回这个集合的迭代器;toArray()集合变成数组或者序列;
37.3、LinkedList(是一个列表)
注意:add()和addLast()的区别
-
package com.example.test;
-
-
import java.util.LinkedList;
-
import java.util.List;
-
-
-
public class LinkedListDemo {
-
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
NewTitle news1=new NewTitle(1,"title1","admin");
-
NewTitle news2=new NewTitle(2,"title2","admin");
-
NewTitle news3=new NewTitle(3,"title3","admin");
-
NewTitle news4=new NewTitle(4,"title4","admin");
-
-
LinkedList list=new LinkedList();
-
//List list=new ArrayList();//这种接口是向上转移,面向接口编程的时候经常用
-
list.add(news1);
-
list.add(news2);
-
list.add(news3);
-
list.add(1,news4);
-
-
System.out.println(list.contains(news4));
-
-
-
int nums=list.size();
-
System.out.println("共有"+nums+"条标题");
-
System.out.println("*******************");
-
for(int i=0;i<nums;i++) {
-
NewTitle newsTitle=(NewTitle) list.get(i);//找到对应位置上的元素;即:Object
-
System.out.println(newsTitle.getNewsName());
-
}
-
NewTitle news5=new NewTitle(5,"titleFirst","admin");
-
NewTitle news6=new NewTitle(6,"titleLast","admin");
-
NewTitle news7=new NewTitle(7,"title","admin");
-
-
list.addFirst(news5);
-
list.addLast(news6);//在当前基础上添加的末尾;
-
list.add(news7);//在集合的尾部依次添加;所以在news6的后面
-
int nums1=list.size();
-
System.out.println("*******************");
-
-
for(int i=0;i<nums1;i++) {
-
NewTitle newsTitle=(NewTitle) list.get(i);//找到对应位置上的元素;即:Object
-
System.out.println(newsTitle.getNewsName());
-
}
-
System.out.println("**********************");
-
list.removeFirst();
-
list.removeLast();
-
NewTitle t=(NewTitle)list.removeFirst();
-
for (int i=0;i<list.size();i++) {
-
NewTitle newsTitle=(NewTitle)list.get(i);
-
System.out.println(newsTitle.getNewsName());
-
}
-
}
-
-
}
eclipse调试F6是跳过方法,F5是进入放法;
注意:ArrayList再插入元素时,是插入位置的元素依次往后移;
LinkedList在插入元素时,只是插入结点位置不一样;其他不变,只是修改next和previous
LinkedList常用方法:
总结:
37.4、HashSet
java虚拟机会管理内存空间,可能划分为栈(存放平时的变量),堆(存放的是对象),方法区(和类相关的字节码数据、类中的方法)
new:生成对象;
类型 变量:是变量;
Set存放的就是对象的引用,s1、s2引用的同一个对象;所以s1和s2是重复的对象;
Set是类似于map的一个数据结构;
HashMap有个hash码,计算两个hash码,如果java和Java的hash码一样或者相近的,就会放到一个地方,同一个位置。
若不同key的hascode相同,则存储在同一个数组地址链表上,存储格式为entry(key,value)
第一、set增加位置是随机的,先加的s1还是s2不确定,总之最后添加的会覆盖掉重复的;
set接口如何判断加入对象是否已经存在呐?
采用对象的equals()方法比较两个对象是否相等,即时候指向的是同一个对象;若返回值是True,则后面的值会覆盖掉前面的值!注意:在String中equals是比较两个字符串的内容(可以是分别new的)是否一样,可能是两个引用,String类重写过equals方法,只要字符串值一样,则认为是一个对象,set就会只加一个!
注意set中没有get方法:因为set中是无序的,存放的时候是乱的,所以不能通过下标找到对应元素;
那如何实现元素输出呐?
答:可以通过增强型for来进行;
迭代器可以定位到集合里面的每一个元素:有方法hasnext(),判断有没有下一个元素---返回boolean;如果有(hasnext)下一个元素,取下一个元素就是next()方法;
iterator遍历的时候是拿元素作为一个集合去遍历;不会像是数组一样从0开始去找;找元素的集合;
-
package com.example.test;
-
-
import java.util.HashSet;
-
import java.util.Iterator;
-
import java.util.Set;
-
-
public class SetDemo {
-
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
Set set=new HashSet();
-
String s1=new String("java");
-
String s2=s1;
-
String s3=new String("Java");
-
String s4=new String("JDK");
-
System.out.println(s1.equals(s2));//即值不一样
-
System.out.println(s3.equals(s1));
-
set.add(s1);
-
set.add(s2);
-
set.add(s3);
-
set.add(s4);
-
System.out.println(set.size());
-
//方法一:增强型for
-
for(Object obj:set) {//拿出set的每个元素放到obj中
-
String sObj=(String)obj;
-
System.out.println(sObj);
-
}
-
System.out.println("********************");
-
//方法二:迭代器(与类型是无关的)
-
Iterator itor=set.iterator();//是Collection中方法
-
while(itor.hasNext()) {
-
String sItor=(String)itor.next();
-
System.out.println(sItor);
-
}
-
}
-
-
}
运行结果为:
list获取元素的方法:
set获取元素的方法:
List和Set是Collection的子接口,注意接口可以多继承,但是没有办法实例化,
Map不是Collection的子接口;
Ctrl+shift+o是导入多个包;
Iterator迭代器,是与Collection和Map无关的一个接口
37.5 Map
Map:中的key是唯一的,无序是Set;值value可以重复,还无序,是Collection
-
package com.example.test;
-
-
import java.util.HashMap;
-
import java.util.Iterator;
-
import java.util.Map;
-
import java.util.Set;
-
-
public class MapDemo {
-
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
//Map map=new HashMap();
-
HashMap map=new HashMap();
-
map.put("China", "中国");//相当于List的add,第一个参数是key,第二个参数是value
-
map.put("FR","法国");
-
map.put("JP","日本");
-
System.out.println(map.size());
-
//如何获取元素?
-
Set s=map.keySet();
-
-
Iterator itor=s.iterator();
-
while(itor.hasNext()) {
-
String keystr=(String)itor.next();
-
String valstr=(String)map.get(keystr);
-
System.out.println(valstr);
-
}
-
System.out.println("**************");
-
for(Object obj:s) {
-
String se=(String)obj;
-
String valstr=(String)map.get(se);
-
System.out.println(valstr);
-
}
-
}
-
-
}
运行结果:
迭代器是什么类型的接口?
答:Iterator类型的;接口也是一种类型,可通过接口声明接口类型的对象,只不过new的时候没有办法创建接口类的对象,因为接口没有办法实例化。接口有实现类,即通过父类类型指向子类类型对象。也叫创建了一个接口类的对象。
map中的方法Set<Map.Entry<K,V>> entrySet():返回键值对集合,类型是Map.Entry<K,V>的集合Set,如下图;
-
package com.example.test;
-
-
import java.util.HashMap;
-
import java.util.Iterator;
-
import java.util.Map;
-
import java.util.Set;
-
-
public class MapDemo {
-
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
//Map map=new HashMap();
-
HashMap map=new HashMap();
-
map.put("China", "中国");//相当于List的add,第一个参数是key,第二个参数是value
-
map.put("FR","法国");
-
map.put("JP","日本");
-
System.out.println(map.size());
-
//如何获取元素?
-
Set s=map.keySet();//返回所有的 键
-
System.out.println(s);
-
//方法一:通过迭代器获取值
-
Iterator itor=s.iterator();
-
while(itor.hasNext()) {
-
String keystr=(String)itor.next();
-
String valstr=(String)map.get(keystr);
-
System.out.println(keystr+"---"+valstr);
-
}
-
//通过键获取值
-
System.out.println("**************");
-
for(Object obj:s) {
-
String se=(String)obj;
-
// if (se.equals("China")) {;
-
// //map.remove(se);
-
// }
-
// else {
-
String valstr=(String)map.get(se);
-
System.out.println(se+"---"+valstr);
-
// }
-
}
-
-
//方法三:获得键值对
-
System.out.println("**************");
-
Set kvSets=map.entrySet();//Set中每个元素都是Map.Entry类型,键值对形式
-
for(Object me:kvSets) {
-
Map.Entry meNew=(Map.Entry)me;
-
String key=(String)meNew.getKey();
-
String value=(String)meNew.getValue();
-
System.out.println(key+"---"+value);
-
}
-
System.out.println("*************");
-
map.clear();
-
System.out.println(map.isEmpty());
-
}
-
-
}
运行结果:
练习题:
38、泛型:
解决了,取元素时,不用再强制类型转换;
所有的集合类和接口都实现了泛型;
解释:ArrayList数组以前能放Object类型的对象,现在加上泛型后只能装Student类型的对象。取数据时就不用再进行类型转换了!而Poem类型的对象是不能加到ArrayList中的。
操作空对象就会报NullpointerException,即null.say();
泛型的好处:数据添加的时候更安全;往外取数据的时候不用再类型转换;
ArrayList用泛型:
-
package com.example.test;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
-
public class ArrayListDemo {
-
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
NewTitle news1=new NewTitle(1,"title1","admin");
-
NewTitle news2=new NewTitle(2,"title2","admin");
-
NewTitle news3=new NewTitle(3,"title3","admin");
-
NewTitle news4=new NewTitle(4,"title4","admin");
-
-
//ArrayList list=new ArrayList();
-
//List list=new ArrayList();//这种接口是向上转移,面向接口编程的时候经常用
-
ArrayList <NewTitle> list=new ArrayList<NewTitle>();
-
-
list.add(news1);
-
list.add(news2);
-
list.add(news3);
-
list.add(1,news4);
-
//list.add("aaa");
-
System.out.println(list.contains(news4));
-
-
int nums1=list.size();
-
System.out.println("共有"+nums1+"条标题");
-
-
System.out.println(list.remove(news4));//boolean
-
System.out.println(list.remove(1));//Object
-
int nums=list.size();
-
System.out.println("共有"+nums+"条标题");
-
System.out.println("*******************");
-
for(int i=0;i<nums;i++) {
-
NewTitle newsTitle=list.get(i);//找到对应位置上的元素;即:Object
-
System.out.println(newsTitle.getNewsName());
-
}
-
System.out.println(list.toArray());
-
list.clear();
-
System.out.print(list.isEmpty());
-
int nums2=list.size();
-
System.out.println("共有"+nums2+"条标题");
-
}
-
-
}
运行结果:
Map用泛型:
每个Map.Entry键值对的键类型是String,值类型是String,所以有Map.Entry<String,String>,所有的键值对又是组成Set。所以有了类型Set<Map.Entry<String,String>>
-
package com.example.test;
-
-
import java.util.HashMap;
-
import java.util.Iterator;
-
import java.util.Map;
-
import java.util.Set;
-
-
public class MapDemo {
-
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
//Map map=new HashMap();
-
HashMap<String,String> map=new HashMap<String,String>();
-
map.put("China", "中国");//相当于List的add,第一个参数是key,第二个参数是value
-
map.put("FR","法国");
-
map.put("JP","日本");
-
System.out.println(map.size());
-
//如何获取元素?
-
Set<String> s=map.keySet();//返回所有的 键
-
System.out.println(s);
-
//方法一:通过迭代器获取值
-
Iterator<String> itor=s.iterator();
-
while(itor.hasNext()) {
-
String keystr=itor.next();
-
String valstr=map.get(keystr);
-
System.out.println(keystr+"---"+valstr);
-
}
-
//通过键获取值
-
System.out.println("**************");
-
for(String obj:s) {
-
String se=obj;
-
// if (se.equals("China")) {;
-
// //map.remove(se);
-
// }
-
// else {
-
String valstr=map.get(se);
-
System.out.println(se+"---"+valstr);
-
// }
-
}
-
-
//方法三:获得键值对
-
System.out.println("**************");
-
Set<Map.Entry<String,String>> kvSets=map.entrySet();//Set中每个元素都是Map.Entry类型,键值对形式
-
for(Map.Entry<String,String> me:kvSets) {
-
//Map.Entry<String,String> meNew=(Map.Entry<String,String>)me;
-
String key=me.getKey();
-
String value=me.getValue();
-
System.out.println(key+"---"+value);
-
}
-
System.out.println("*************");
-
map.clear();
-
System.out.println(map.isEmpty());
-
}
-
-
}
运行结果为:
39、Collections:
调用sort方法时,会根据集合里面的类型(比如是元素是:String)的自然排序规则(就是比较字母在26个里面的ASCII)去排序;
但是如果集合里面是Dog类型呐?怎么排序呐?
compareTo()的方法体就是排序规则;
对集合中的什么类型进行排序,就让该类要实现Comparable接口,去重写compartTo()方法;
-
package com.example.test;
-
-
public class Student implements Comparable{//实现接口,普通类得把接口的抽象方法给实现;
-
private int id;
-
private String name;
-
private String sex;
-
public Student() {
-
super();//Object为父类
-
// TODO Auto-generated constructor stub
-
}
-
public Student(int id,String name,String sex) {
-
super();
-
this.id=id;
-
this.name=name;
-
this.sex=sex;
-
}
-
//Shift+alt+s
-
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 String getSex() {
-
return sex;
-
}
-
public void setSex(String sex) {
-
this.sex = sex;
-
}
-
@Override
-
public int compareTo(Object o) {
-
// TODO Auto-generated method stub
-
//如果我比你大,则返回1;
-
//stu是传过来要进行比较的学生对象;
-
Student stu=(Student)o;
-
//要让stu和我当前的这个学生对象(this)进行比较;
-
if(this.id==stu.id) {
-
return 0;
-
}
-
else if (this.id>stu.id) {
-
return 1;
-
}
-
else if (this.id<stu.id) {
-
return -1;
-
}
-
return 0;
-
}
-
}
-
package com.example.test;
-
-
import java.util.ArrayList;
-
import java.util.Collections;
-
-
public class StuListDemo {
-
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
Student stu1=new Student(1,"zhangsan","男");
-
Student stu2=new Student(2,"zhangsan2","男");
-
Student stu3=new Student(3,"zhangsan3","男");
-
ArrayList<Student> list=new ArrayList<Student>();
-
list.add(stu1);
-
list.add(stu2);
-
list.add(stu3);
-
Collections.sort(list);//不知道student类型按什么排序;得自定义排序规则
-
for(Student stu:list) {
-
System.out.println(stu.getId()+"--"+stu.getName());
-
}
-
}
-
-
}
运行结果:
用name来比较大小呐?
-
package com.example.test;
-
-
import java.util.ArrayList;
-
import java.util.Collections;
-
-
public class StuListDemo {
-
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
Student stu1=new Student(1,"zhangsan","男");
-
Student stu2=new Student(2,"heh","男");
-
Student stu3=new Student(3,"yes","男");
-
ArrayList<Student> list=new ArrayList<Student>();
-
list.add(stu1);
-
list.add(stu2);
-
list.add(stu3);
-
Collections.sort(list);//不知道student类型按什么排序;得自定义排序规则
-
for(Student stu:list) {
-
System.out.println(stu.getId()+"--"+stu.getName());
-
}
-
}
-
-
}
-
package com.example.test;
-
-
public class Student implements Comparable{//实现接口,普通类得把接口的抽象方法给实现;
-
private int id;
-
private String name;
-
private String sex;
-
public Student() {
-
super();//Object为父类
-
// TODO Auto-generated constructor stub
-
}
-
public Student(int id,String name,String sex) {
-
super();
-
this.id=id;
-
this.name=name;
-
this.sex=sex;
-
}
-
//Shift+alt+s
-
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 String getSex() {
-
return sex;
-
}
-
public void setSex(String sex) {
-
this.sex = sex;
-
}
-
@Override
-
public int compareTo(Object o) {
-
// TODO Auto-generated method stub
-
//如果我比你大,则返回1;
-
//stu是传过来要进行比较的学生对象;
-
// Student stu=(Student)o;
-
// //要让stu和我当前的这个学生对象(this)进行比较;
-
// if(this.id==stu.id) {
-
// return 0;
-
// }
-
// else if (this.id>stu.id) {
-
// return 1;
-
// }
-
// else if (this.id<stu.id) {
-
// return -1;
-
// }
-
// return 0;
-
String s="aaa";
-
Student stu=(Student)o;
-
return this.name.compareTo(stu.name);//String 类已经重写过compareTo了。要用规则直接调用即可;
-
}
-
}
运行结果:
其中String类中compartTo()方法是:
40.枚举类型
具有含义的常量:
参考CSDN:https://blog.csdn.net/huanhuanq1209/article/details/80636730
41.
Java优秀教程的更多相关文章
- Java IO教程
1 Java IO 教程 2 Java IO 概述 3 Java IO: 文件 4 Java IO: 管道 5 Java IO: 网络 6 Java IO: 字节和字符数组 7 Java IO: S ...
- Java NIO教程 目录
"Java NIO系列教程" 是笔者hans为NIO的初学者编写的一份入门教程,想仔细学习的同学可以按照顺序去阅读.由于我学的也不是特别的精,所以错误.疏漏在所难免,希望同学们指正 ...
- 优秀教程:使用 CSS3 动画实现的超炫的过渡特效
Codrops 最近分享了一些很酷的图片切换灵感.有三种不同的用例:小的图像幻灯片,大标题幻灯片以及使用透明背景的产品幻灯片.状态转换使用 CSS 动画完成,我们能够定义从任何方向进来的图片的行为. ...
- 学习制作精美 CSS3 按钮效果的10个优秀教程
由于互联网世界正在发生变化,人们往往喜欢那些有更多互动元素的网站,因此现在很多 Web 开发人员也在专注于提高他们的 CSS3 技能,因为 CSS3 技能可以帮助他们在很大的程度上实现所需的吸引力.这 ...
- Java入门教程总目录
Java入门教程总目录 持续更新中... 1.Java常识汇总 2.Java框架对比 3.Java技术路线 4.Java编码规范 5.Java环境变量配置 6.枚举 7.操作符 12.定时任务
- Java注解教程:自定义注解示例,利用反射进行解析
Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响.在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解. 注解是Java 1.5引入 ...
- Java自学教程视频
BAT大咖助力 全面升级Android面试 BAT大牛亲授 基于ElasticSearch的搜房网实战 从天气项目看Spring Cloud微服务治理 Java企业级电商项目架构演进之路 Tomca ...
- java学习教程与笔记
一个java学习教程:http://www.jikexueyuan.com/path/java/#stage1 集合类学习: java中结合类很多,但用得比较多的一般有三种,当然,其它语言也是,主要是 ...
- 正在学习的Java大学教程
推荐本书<Java大学教程> 看的人比较少,我也是多年不看书了,基于教程一般选国外的方法,从图书馆选了本书. 看了一半,感觉书的内容比较认真,对于基本的Java知识都算介绍全了,而且全书是 ...
随机推荐
- [WPF]总结一些我在开发WPF时常用的工具
我从一万二千年前开始写XAML,这么多年用了很多各式各样的工具,现在留在电脑里的.现在还在用的.在写WPF时用的也就那么几个.这篇文章总结了这些工具,希望这些工具可以让WPF开发者事半功倍. 1. V ...
- bugku论剑场web解题记录
前言 国庆这几天感觉没什么好玩的地方,家又离的太远,弱鸡的我便决定刷刷题涨涨知识,于是就有了这篇文章.. 正文 写的不对的地方欢迎指正 web26 打开直接就是代码,这应该就是一道代码审计的题了 这里 ...
- TCP、UDP服务器模型 在网络程序里面,通常都是一
TCP.UDP服务器模型 在网络程序里面,通常都是一个服务器处理多个客户机,为了出个多个客户机的请求,服务器端的程序有不同的处理方式. 目前最常用的服务器模型: 循环服务器:循环服务器在同一时刻只能响 ...
- 一书吃透机器学习!新版《机器学习基础》来了,教材PDF、PPT可下载 | 资源
不出家门,也能学习到国外高校的研究生机器学习课程了. 今天,一本名为Foundations of Machine Learning(<机器学习基础>)的课在Reddit上热度飙升至300, ...
- iOS pch
Xcode6 之前会在 Supporting Files 文件夹下自动生成一个"工程名-PrefixHeader.pch"的预编译头文件,pch 头文件的内容能被项目中的其他所有源 ...
- Ubuntu查看文件格式(后缀名)
在文件目录执行: $ file filename #filename表示要查看的文件名
- Android进阶AIDL使用自定义类型
原文首发于微信公众号:jzman-blog,欢迎关注交流! 上篇文章中主要介绍从 AIDL 的使用方式以及 Android 开发中不同进程之间的通信,遗留的问题是如何在 AIDL 中使用自定义类型,具 ...
- IE,Google Chrome等浏览器,调试模式在控制台可以手动调用页面的方法来调试
IE,Google Chrome等浏览器,调试模式在控制台可以手动调用页面的方法来调试,这种方式也可以进断点.
- Activiti网关--并行网关
1.什么是并行网关 并行网关允许将流程分成多条分支,也可以把多条分支汇聚到一起,并行网关的功能是基于进 入和外出顺序流的: fork 分支: 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支. ...
- C/C++知识总结 一 C/C++常识概述
C/C++常识概述 程序与计算机语言 C/C++简介与发展 C/C++异同 C/C++编译特点 学习编程建议 程序与计算机语言 程序:是一组计算机能识别和执行.预先编好的一些指令操作合集. 计算机语言 ...