1-instanceof 用法总结.
instanceof和类型转换运算符一样,都是Java提供的运算符,与+、-等算术运算符的用法大致相似。
instanceof运算符的前一个操作数通常是一个引用类型变量,后一个操作数通常是一个类(也可以是一个接口),它用于判断前面的对象是否是后面的类,或者是其子类、实现类的接口。如果是,返回true,否则返回false。
在使用instanceof运算符需要注意:instanceof运算符前面的操作数的编译时类型要么和后面的类相同,要么和后面的类具有父子继承关系,否则会引发编译错误。
在Java开发中,通常联合使用instanceof和强制转换(type)两个运算符,先使用instanceof判断一个对象是否可以强制类型转换,然后再使用强制转换符(type)对对象进行强制转换,从而保证程序不会出错。
2-泛型:常见的字母及分别对应含义?
Java中一些常见的泛型的类型变量:
泛型的类型变量 | 意义 |
---|---|
E | 元素(Element),多用于java集合框架 |
K | 关键字(Key),多用于Map集合 |
N | 数字(Number) |
T | 类型(Type) |
V | 值(Value),多用于Map集合 |
3-泛型的优点是安全和省心,请用代码说明。
package com.bjsxt.MyCollection;
import java.util.ArrayList;
import java.util.List;
public class TestGeneric {
public static void main(String[] args) {
//创建一个只想保存字符串的list集合
List strList = new ArrayList();
strList.add("我");
strList.add("是");
strList.add("中国人");
//程序试图将一个Integer对象放入集合中
strList.add(100);//(1)
for(int i = 0; i < strList.size(); i++) {
String s = (String)strList.get(i);//(2)
System.out.println(s.length());
}
}
}
程序输出结果:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at com.bjsxt.MyCollection.TestGeneric.main(TestGeneric.java:19)
1
1
3
上面的程序创建了一个List集合,而且只希望该List集合保存字符串对象——但程序没有进行任何限制,结果程序在(1)处把一个Integer对象放入List集合中,这导致在(2)处由于程序试图把一个Integer对象转换成String类型,而引发ClassCastException异常。
从Java5以后,Java引入了“参数化类型”的概念,允许程序在创建集合时指定集合元素的类型List<String>
,保证程序在创建集合时只能保存字符串类型的对象。
还是上面的代码:
package com.bjsxt.MyCollection;
import java.util.ArrayList;
import java.util.List;
public class TestGeneric {
public static void main(String[] args) {
//创建一个只想保存字符串的list集合
List<String> strList = new ArrayList<String>();//(1)
strList.add("我");
strList.add("是");
strList.add("中国人");
//程序试图将一个Integer对象放入集合中
//下面的这行代码将直接引起编译错误
strList.add(100);//(2)
for(int i = 0; i < strList.size(); i++) {
String s = strList.get(i);//(3)
System.out.println(s.length());
}
}
}
上面的程序在(1)处创建了一个只能保存String类型的List集合,在(2)处编译器编译时就会报错,因为strList集合只能添加String对象,所以不能将Integer对象放入该集合。
而且程序在(3)处不需要进行强制类型转换,因为strList对象可以“记住”它的所有集合元素都是String类型。
4-泛型接口注意事项是是么?
泛型接口在定义时可以使用泛型,但是在使用时必须要传入实际的类型参数,或者不带泛型(如子类继承)。举例如下:
package com.bjsxt.test;
/**
* 定义一个泛型类
* @author WL20180723
*
* @param <T>
*/
public class Apple<T> {
private T info;
public Apple() {}
public Apple(T info) {
super();
this.info = info;
}
public T getInfo() {
return info;
}
public void setInfo(T info) {
this.info = info;
}
}
//定义类A继承Apple类,Apple类不能跟类型形参
public class A extends Apple<T>{ } //错误
如果想从Apple类派生一个子类,则可以改为如下代码:
//使用Apple类时,为T形参传入String类型
public class A extends Apple<Sting>{ } //正确
使用类或者接口时,也可以不为类型形参传入实际的类型参数,即下面的代码也是正确的。
//使用Apple类时不为T形参传入实际的类型参数
public class A extends Apple{ } //正确
5-泛型方法注意事项是什么?
带有泛型声明的方法被称为泛型方法,方法中的形参代表变量、常量、表达式等数据。定义方法时可以声明泛型形参,但是在调用方法时必须为这些’泛型的形参传入实际的参数值。
如下代码所示:
package com.bjsxt.test;
public class A1 extends Apple<String>{
//正确的重写了父类的方法,返回值与父类Apple<String>的返回值相同
public String getInfo() {
return "子类" + super.getInfo();
}
//下面的方法是错误的,重写方法的返回值与父类的返回值不同
// public Object getInfo() {
//
// }
}
A1继承了Apple类,则在Apple类中所有的T类型形参的地方,都将被替换成String类型,子类也都会继承这些方法。
还有Apple在被继承时,没有传入实际的类型参数:
package com.bjsxt.test;
public class A2 extends Apple {
//重写父类的方法
//super.getInfo()方法返回值是Object类型,所以加上了toString()
public String getInfo() {
return "子类" + super.getInfo().toString();
}
}
此时,Java编译器可能会发出警告:使用了未经检查或者不安全的操作——这就是泛型检查的警告。
看看下面的代码的打印结果是什么?
//分别创建List<String>和List<Integer>对象
List<String> strList = new ArrayList<String>();
List<Integer> intList = new ArrayList<Integer>();
System.out.println(strList.getClass() == intList.getClass());
结果:
true
运行之后发现结果为true,因为不管泛型的实际类型参数是String、Integer或者其它的类型,它们在运行时总有同样的类(class)。
在静态方法、静态初始化块或者静态变量的声明和初始化中不允许使用泛型(类型参数)。instanceof运算符后也不能使用泛型类。
6-泛型:(1)子类指定具体类型,(2)子类为泛型类,(3)子类为泛型类/父类不指定类型,(4)子类与父类同时不指定类型,以上4点请分别用代码举例。
package com.bjsxt.gen;
/**
* 泛型接口
* @author WL20180723
*
*/
public interface Comparable<T> {
void compare(T t);
}
//子类指定具体类型
class Comp5<String> implements Comparable<String>{
public void compare(String t) {
}
}
//子类泛型
class Comp2<T> implements Comparable<T>{
public void compare(Object t) {
}
}
//子类泛型,父类不指定泛型
class Comp3<T> implements Comparable{
public void compare(T t) {
}
}
//子类和父类都不指定泛型
class Comp1 implements Comparable{
public void compare(Object t) {
}
}
7-泛型接口,方法是以父类而定还是以子类而定?
方法以父类而定
8-形参使用多态、返回类型使用多态 请分别代码举例。
形参多态:
package com.bjsxt.MyCollection;
import java.util.ArrayList;
import java.util.List;
/**
* 形参多态
* @author WL20180723
*
*/
public class Animal {
public void eat() {
System.out.println("Animal is eatting!!!");
}
public static void main(String[] args) {
List<Animal> list = new ArrayList<Animal>();
list.add(new Animal());//形参多态
list.add(new Dog());//形参多态
list.add(new Cat());//形参多态
for(Animal a : list) {
a.eat();
}
}
}
class Dog extends Animal{
public void eat() {
System.out.println("Dog is eatting!!!");
}
}
class Cat extends Animal{
public void eat() {
System.out.println("Cat is eatting!!!");
}
}
返回类型多态:
package com.bjsxt.MyCollection;
import java.util.ArrayList;
import java.util.List;
/**
* 返回值多态
* @author WL20180723
*
*/
public class Animal {
public void eat() {
System.out.println("Animal is eatting!!!");
}
public static void main(String[] args) {
List<Animal> list = new ArrayList<Animal>();
list.add(new Animal());
list.add(new Dog());
list.add(new Cat());
for(int i = 0; i < list.size(); i++) {
Animal animal = list.get(i);//返回值多态
animal.eat();
}
}
}
class Dog extends Animal{
public void eat() {
System.out.println("Dog is eatting!!!");
}
}
class Cat extends Animal{
public void eat() {
System.out.println("Cat is eatting!!!");
}
}
9-泛型有没有多态?
泛型没有多态
10-泛型的?问号: 只能声明在类型|方法上,不能声明类或者使用时,请用代码证明这句话的正确性.
package com.bjsxt.gen;
public class Student<T> {
T score;
public static void main(String[] args) {
Student<?> s = new Student<String>();
test(new Student<Integer>());
test2(new Student<Apple>());
Integer[] arr = new Integer[10];
// Student<String>[] arr2 = new Student<String>[10];//不能创建泛型数组
Student<?>[] arr2 = new Student[10];
}
public static void test(Student<?> s) {
}
public static void test3(Student<Fruit> s) {
}
public static void test2(Student<? extends Fruit> s) {
}
}
11-泛型嵌套:由外到内拆分.请用代码解释这句话.
先定义一个Studen泛型类:
package com.bjsxt.gen;
/**
* ?类型不确定,使用时确定类型
* ?:在声明类型或者方法时使用,不能在声明类或者使用时使用
* ?extends:<= 上限 指定类型为子类或自身
* ?super:>=下限,指定类型为自身或者父类
* 没有泛型数组
* @author WL20180723
*
* @param <T>
*/
public class Student<T> {
T score;
public static void main(String[] args) {
Student<?> s = new Student<String>();
// Student<?> s1 = new Student<?>();
test(new Student<Integer>());
test2(new Student<Apple>());
// test3(new Student<Apple>());//泛型没有多态
//
Integer[] arr = new Integer[10];
// Student<String>[] arr2 = new Student<String>[10];//不能创建泛型数组
Student<?>[] arr2 = new Student[10];
}
public static void test(Student<?> s) {
}
public static void test3(Student<Fruit> s) {
}
public static void test2(Student<? extends Fruit> s) {
}
}
接着定义一个TestStudent类:
package com.bjsxt.test;
/**
* 测试泛型嵌套
* @author WL20180723
*
* @param <T>
*/
public class TestStudent<T> {
T stu;
public T getStu() {
return stu;
}
public void setStu(T stu) {
this.stu = stu;
}
public static void main(String[] args) {
Student<Integer> student = new Student<Integer>();
student.setScroe(98);
//嵌套
TestStudent<Student<Integer>> test = new TestStudent<Student<Integer>>();
test.setStu(student);
System.out.println(test.getStu().getScroe());
}
}
12-泛型有没有数组?
泛型没有数组
13-用匿名内部类实现迭代器。
package com.bjsxt.test;
import java.util.Iterator;
public class MyIterator3 {
String[] elementData = {"a","b","c","d","e","f","g"};
int size = elementData.length;
//匿名内部类
public Iterator<String> iterator() {
return new Iterator<String>() {
private int cursor = -1;
/**
* 是否还有下个元素
* @return
*/
public boolean hasNext() {
return cursor + 1 < size;
}
//下一个元素
public String next() {
cursor++;//指针移动一次
return elementData[cursor];
}
public void remove() {
//没有实现
}
};
}
public static void main(String[] args) {
MyIterator3 it = new MyIterator3();
Iterator<String> iterator = it.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
//使用增强for循环,必须实现java.lang.Iterable<String>
//for(String s : it) {
// System.out.println(s);
//}
}
}
输出结果:
a
b
c
d
e
f
g
14-用分拣思路统计字符串出现次数"this-is-my-first-dog-but-i-like-cat-and-cat-is-nice-and-dog-is-friendly-this-why-i-like-cat-more".
package com.bjsxt.test;
import java.util.HashMap;
import java.util.Map;
public class CountWords {
public static void main(String[] args) {
String str = "this-is-my-first-dog-but-i-like-cat-and-cat"
+ "-is-nice-and-dog-is-friendly-this-why-i-like-cat-more";
Map<String, Letter> map = new HashMap<String, Letter>();
String[] strArray = str.split("-");
for(String s : strArray) {
Letter let = null;
let = map.get(s);
if(let == null) {
let = new Letter();
map.put(s, let);
let.setCount(1);
}else {
let.setCount(let.getCount() + 1);
}
}
for(String s : map.keySet()) {
System.out.println(s + "\t出现\t" + map.get(s).getCount() + "次");
}
}
}
程序运行结果如下:
but 出现 1次
like 出现 2次
friendly 出现 1次
more 出现 1次
this 出现 2次
i 出现 2次
why 出现 1次
is 出现 3次
my 出现 1次
nice 出现 1次
and 出现 2次
cat 出现 3次
dog 出现 2次
first 出现 1次
15-用面向对象思想+分拣思路统计班级总人数和平均分。
学生类:
package com.bjsxt.test;
public class Student {
private String name;
private String number;
private Double score;
public Student() {
}
public Student(String name, String number, Double score) {
super();
this.name = name;
this.number = number;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
}
班级类:
package com.bjsxt.test;
import java.util.ArrayList;
import java.util.List;
public class ClassRoom {
private String number;
private List<Student> students;
private double total;
public ClassRoom() {
students = new ArrayList<Student>();
}
public ClassRoom(String number) {
this();
this.number = number;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
public double getTotal() {
return total;
}
public void setTotal(double total) {
this.total = total;
}
}
测试:
package com.bjsxt.test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* 定义一个Student类,属性:name姓名,classNumber班号,score成绩
* 现在将若干student对象放入List,请统计出每个班级的总分和平均分,分别打印出来
* @author WL20180723
*
*/
public class MapDemo {
public static void main(String[] args) {
List<Student> list = new ArrayList<Student>();
exam(list);
//统计
Map<String, ClassRoom> rooms= new HashMap<String, ClassRoom>();
count(rooms, list);
//打印总分和平均分
printScore(rooms);
}
/**
* 若干学生加入到List
* @param list
*/
public static void exam(List<Student> list) {
list.add(new Student("a", "001", 86D));
list.add(new Student("b", "002", 80D));
list.add(new Student("c", "003", 81D));
list.add(new Student("d", "004", 80D));
}
/**
* 统计分数
*/
public static void count(Map<String, ClassRoom> rooms, List<Student> list) {
for(Student s : list) {
String number = s.getNumber();
Double score = s.getScore();
//根据班级编号查看map是否存在改班级,分拣思路
ClassRoom room = rooms.get(number);
if(room == null) {
room = new ClassRoom(number);//第一次
rooms.put(number, room);
}
//存储数据
room.setTotal(room.getTotal() + score);
room.getStudents().add(s);
}
}
public static void printScore(Map<String, ClassRoom> rooms) {
Set<Entry<String, ClassRoom>> entrySet = rooms.entrySet();
Iterator<Entry<String, ClassRoom>> iterator = entrySet.iterator();
while(iterator.hasNext()) {
Entry<String, ClassRoom> entry = iterator.next();
ClassRoom room = entry.getValue();
double avg = room.getTotal() / room.getStudents().size();
System.out.println("班号:" + room.getNumber() + ",总分:" + room.getTotal() + ",平均分:" + avg);
}
}
}
程序输出结果:
班号:001,总分:86.0,平均分:86.0
班号:002,总分:80.0,平均分:80.0
班号:003,总分:81.0,平均分:81.0
班号:004,总分:80.0,平均分:80.0