快捷键 | 功能 |
---|---|
shift+F6 |
选中目标内容后,更改所有用到它的内容 |
ctrl+Y |
删除当前行 |
ctrl+D |
复制当前行 |
Alt+Enter |
导入包自动修正代码 |
Ctrl+Alt+L |
格式化代码 |
Ctrl+/ |
单行注释,再按取消 |
ctrl+shift+/ |
选中代码注释,再按取消 |
Alt+Ins |
自动生成代码:如toString,set,get等方法 |
Alt+Shift+上下箭头 |
移动当前行 |
Shift+F6 |
更改类文件名称 |
ctrl+alt+t |
包括代码块,添加try-catch等信息 |
数组名称.length
1.方法应该定义在类中,不能在方法中定义方法
2.方法定义的前后顺序无所谓
1.要求具有不同的参数列表(参数个数不同,参数数据类型不同,参数的数据类型排列顺序不同,满足其一即可)
2. 修饰符如`public,static`等无关
int[]arr=new int[10];
//或者拆分成两个步骤
int[]arr;
arr=new int[10];
int[]arr=new int[]{1,2,3};
//或者分为两步
int[]arr;
arr=new int[]{1,2,3};
int[]arr={1,2,3};
abstract
和final
不能同时使用,因为矛盾public final class...
修饰符 final 返回值类型
‘public > protected > (default) > private
public | protected | (default) | private | |
---|---|---|---|---|
同一个类 | √ | √ | √ | √ |
同一个包 | √ | √ | √ | × |
不同包子类 | √ | √ | × | × |
不同包非子类 | √ | × | × | × |
分类:1.成员内部类 2.局部内部类(包含匿名内部类)
格式:直接定义在类体内就行
注意:内用外,随意访问;外用内,需要内部类对象
如何使用内部类?有两种方式:
1.间接方式:在外部类的方法中使用内部类,然后main方法中调用外部类的方法
2.直接方法,公式:外部类名称.内部类名称 对象名=new 外部类名称().new 内部类名称();
public class Outer {
int num=10;
public class Inner{
int num=20;
public void method(){
int num=30;
System.out.println(num);
System.out.println(this.num);
System.out.println(Outer.this.num);
}
}
如果一个类是定义在方法内部的,那么这就是一个局部内部类
局部的含义:只有当前的方法能使用它,出了这个方法就不能使用
格式:
修饰符 class 外部类名称{
修饰符 返回值 外部类方法名称(参数列表){
class 局部内部类名称{
...
}
}
1.外部类:public / (default)
2.成员内部类:public / protected / (default) / private
3.局部内部类:什么都不能写
局部内部类中,如果希望访问所在方法的局部变量,那么这个局部变量必须是有效final的.
备注:从JAVA8+开始,只要局部变量事实不变,那么final关键字可以省略
原因:
1.new出来的对象是在堆当中的
2.局部变量是跟着方法走的,在栈内存中
3.方法运行结束后,立刻出栈,局部变量就会立刻消失
4.但是new出来的对象会一直存在于栈内存中,直到垃圾回收消失。因此该对象会copy一份使用到的变量,方法消失后保证数据依旧存在。故该方法的局部变量不能改变。
如果接口的实现类(或父类的子类)只需要使用唯一的一次,那么就可以省略掉该类的定义,而改为使用匿名内部类
匿名内部类的使用格式:
其中,obj是匿名内部类的对象,匿名内部类省略了繁琐地完整创建一个.class文件
public class Temp {
public static void main(String[] args) {
MyInterface obj=new MyInterface() {
@Override
public void method() {
System.out.println("使用了匿名内部类!");
}
};
obj.method();
}
}
public static void main(String[] args) {
new MyInterface(){
@Override
public void method() {
System.out.println("使用了匿名内部类和匿名对象");
}
}.method();
}
继承性、封装性、多态性
new Person().name="赵丽颖"; //只能使用这一次
extends父类名
,则java虚拟机一般会自动给当定义的类添加默认的选项extends java.lang.Object
。故除了类java.lang.Object之外,任何类都有父类,而且类java.lang.Object是除它自身之外的所有类的父类。super(调用参数列表)
//其中super是关键字,表示直接父类的构造方法。
java.lang.Object
类是所有类的 公共最高父类//Father.java
public class Father {
int num=30;
}
//Son.java
public class Son extends Father {
int num = 20;
public void method() {
int num = 10;
System.out.println("Father:" + super.num);
System.out.println("Son:" + this.num);
System.out.println("Temp:" + num);
}
}
@Override
:这叫做注解,写在方法前面,用来检测是否有效地正确覆盖。(如果报错说明未发生覆盖)super()
调用,所以一定是先调用父类构造方法,后执行子类构造方法super
关键字在子类中调用父类重载构造函数 public Temp01(){
System.out.println("调用无参构造函数");
}
public Temp01(int n){
this();
System.out.println("调用重载构造函数");
}
第三种方法中注意:this()构造方法也必须是语句的第一句
注意:this和super两种构造调用不能同时使用,因为构造方法必须放在第一句,也就必须要保证唯一性
Teacher tom=new Teacher();
Employee a=tom;
()
,将父类型数据转换为子类型数据Teacher tom=new Teacher();
Employee a=tom;
Teacher b=(Teacher)a;
引用类型表达式instanceof引用类型
来判断一个引用表达式所指向的实例对象是否是某种引用类型的实例对象Teacher a=new Teacher();
Employee b=new Employee();
Employee c=a;
则表达式a instanceof Teacher
返回true
表达式a instanceof Employee
返回true
表达式b instanceof Teacher
返回false
表达式c instanceof Employee
返回true
表达式c instanceof Teacher
返回true
instanceof
运算符可以用再引用类型转换中,即先判断一个引用表达式所指向的实例对象是否是目标类型的实例对象,可以避免错误如if(a instanceof Teacher)
b=(Teacher)a;
else b=new Teacher();
静态多态性
指的是在同一个类中同名方法在功能上的重载overload
,这也包括一个类对其父类同名方法在功能上的重载,而且在方法声明的形式上要求同名的方法具有不同的参数列表。这里的方法,可以是成员方法,也可以是构造方法。一般建议,重载的方法应当具有相似的功能。super
可以解决在子类型的成员方法中调用父类型的被覆盖的成员方法的问题。
super.父类型的成员域
super.父类型的成员方法(调用参数列表)
super(父类构造方法的调用参数列表)
;super
对应的关键字是this
,其调用的是同一个类的成员域或成员方法。this.成员变量名
这样标准的类也叫做 Java Bean. 可以使用快捷键Alt+Insert
或菜单中Code-Generate
private String name;
private int id;
static String teacher="胡景月";
private static int idCount=0; //给成员变量赋初值
public Student(String name) {
this.name = name;
id=++idCount;
}
对象.静态内容
,也会被编译成为类.静态内容
API全程Application Programming Interface,应用程序编程接口。
int num=new Scanner(System.in).nextInt();
//还可以使用匿名对象作为参数
public class Demo04Anonymous {
public static void printInt(Scanner sc){
int temp=sc.nextInt();
System.out.println("Num is "+temp);
}
public static void main(String[] args) {
printInt(new Scanner(System.in));
}
}
//匿名对象还可以作为返回值
public static Scanner methodReturn() {
return new Scanner(System.in);
}
Random r=new Random();
int a=r.nextInt(); //范围-21亿到+21亿
Random r=new Random();
for (int i = 0; i < 10; i++) {
int temp = r.nextInt(10);
//范围是[0,10) 左闭右开
System.out.print(temp);
System.out.print(" ");
}
//若想1~10就
r.nextInt(10)+1;
Person[]arr=new Person[3];
Person one=new Person("余丰旭",22);
Person two=new Person("陈香玉",24);
Person three=new Person("小小余",1);
arr[0]=one;
arr[1]=two;
arr[2]=three;
基本类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
ArrayList<String> list = new ArrayList<>();
list.add("余丰旭");
list.add("陈香玉");
list.add("小小余");
System.out.println(list);
public static void main(String[] args) {
String str = new String();
System.out.println("First String is " + str);
char[] arr = {'a', 'b', 'c'};
String str2 = new String(arr);
System.out.println("Second String is " + str2);
byte[] arr_byte = {97, 98, 99};
String str3 = new String(arr_byte);
System.out.println("Third String is " + str3);
String str4="abc";
System.out.println("Forth String is "+str4);
String str1="abc";
String str2="abc";
char[]arr={'a','b','c'};
String str3=new String(arr);
System.out.println(str1==str2); //ture
System.out.println(str1==str3); //false
System.out.println(str2==str3); //false
==
是进行对象的地址值的比较,如果确实需要字符串的内容比较,可以使用两个方法public boolean equals(Object obj):参数可以是任何对象
public boolean equalsIgnoreCase(String str):忽略大小写,进行内容比较
String str1="abc";
String str2="abc";
char[]arr={'a','b','c'};
String str3=new String(arr);
if(str1.equals(str2))
System.out.println("str1=str2");
if(str1.equals(str3))
System.out.println("str1=str3");
if(str1.equals("abc"))
System.out.println("str1=abc");
if("abc".equals(str1))
System.out.println("abc=str1");
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200122191346564.png)
String当中与获取相关的常用方法有:
备注:CharSequence就是说可以接受字符串类型
分割字符串的方法;
public String[ ] split(String regex):根据参数的规则,将字符串切分为若干部分
String str="Yu,Feng,XU";
String[]strString=str.split(",");
注意事项:split方法的参数其实是一个正则表达式,今后学习,今天要注意,如果按照英文句点.
进行切分,必须写\\.
两个反斜杠
Arrays是一个与数组相关的工具类,里面提供了大量静态方法,来实现数组的常见操作(方便,静态方法不用new)
常用方法
public static String toString(数组)
public static void sort(数组)
常用方法:
public static double abc(double num)
public static double ceil(double num)
public static double floor(double num)
public static long round(double num)
因为java中==
对于基本数据类型比较的是数值,对于引用数据类型比较的是地址值,所以对于自己创建的对象,继承了Object类的equals方法,需要对equals方法进行重写
@Override
public boolean equals(Object obj) {
//如果传递进来的是自身,直接返回true,提高程序效率
if(obj==this)
return true;
//如果传空,直接返回false,提高程序效率
if(obj==null)
return false;
//如果不是Student对象,直接返回false
if (!(obj instanceof Student))
return false;
//向下转型,并进行比较
Student stu = (Student) obj;
if (this.age == stu.age && this.name == stu.name)
return true;
return false;
}
Objects
类有一个equals方法,可以容忍空指针(注意不是Object类,是Objects类) public static void main(String[] args) {
Student stu=new Student("余丰旭",22);
Student stu2=null;
boolean b=Objects.equals(stu,stu2);
System.out.println(b);
}
因为其Objects.equals(再次注意不是Object类是Objects类)方法如下
public static boolean equals(Object a,Object b){
return (a==b)||(a!=null&&a.equals(b));
}
@Override
public String toString() {
return name+":"+age+"岁";
}
位于java.util.objects
public static boolean equals(Object a,Object b){
return (a==b)||(a!=null&&a.equals(b));
System.currentTimeMillis()
获取当前系统时间到1970年1月1日00:00:00(英国格林威治时间)经历了多少毫秒(long类型)1.无参构造
Date date=new Date();
System.out.println(date);
输出结果
Mon Jan 27 19:47:17 CST 2020
2.带参构造(long类型)即毫秒值
Date date2=new Date(1580125811479L);
System.out.println(date2);
输出结果
Mon Jan 27 19:50:11 CST 2020
long getTime()
把日期转换为毫秒值DateFormat类是抽象类,不能直接使用。所以需要常用子类java.text.SimpleDateFormat
,这个类需要一个模式来指定格式化或解析的标准,构造方法为:
public SimpleDateFormat(String pattern)
:用给定的模式和默认语言环境的日期符号构造SimpleDateFormat格式规则
标识字母(区分大小写) | 含义 |
---|---|
y | 年 |
M | 月 |
d | 日 |
H | 时 |
m | 分 |
s | 秒 |
备注:更详细的格式规则,请见API文档
写对应的模式,会把模式替换为对应的日期和时间:
yyyy-MM-dd HH:mm:ss
或
yyyy年MM月dd日 HH时mm分ss秒
其中连接符可以任意写
传入date类型的参数,按照SimpleDateFormat中指定的模式输出字符串
Date today=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
System.out.println(sdf.format(today));
输出结果
2020年02月04日 11时55分41秒
把符合模式的字符串解析为Date日期
public Date parse(String source)
throws ParseException
parse方法声明了一个异常叫ParseException解析异常,如果字符串和构造方法中的模式不一样,那么程序就会抛出异常,调用一个抛出了异常的方法,就必须处理这个异常,那么throws继续声明抛出这一个异常,要么try…catch自己处理这个异常(暂时用Alt+enter 让虚拟机自己处理)
Date today=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
Date day=sdf.parse("2020年02月04日 11时55分41秒");
System.out.println("parse方法将符合指定模式的字符串转换为Date类型数据:\n"+day);
输出结果:
parse方法将符合指定模式的字符串转换为Date类型数据:
Tue Feb 04 11:55:41 CST 2020
public class demo02 {
public static void main(String[] args) throws ParseException {
System.out.println("请按照格式输入出生日期: yyyy-MM-dd");
Scanner sc=new Scanner(System.in);
String birthString=sc.next();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date birthday=sdf.parse(birthString);
long birthdayMS=birthday.getTime();
long nowMS=new Date().getTime();
long distance=nowMS-birthdayMS;
System.out.println("此人距出生已经历"+distance/1000/60/60/24+"天");
}
}
很多Date类的方法已被Calendar类替代,java.util.Calendar类是一个抽象类,提供了很多操作日历字段的方法(YEAR,MONTH,DAY_OF_MONTH,HOUR)
Calendar类无法直接创建对象使用,其含有静态方法getInstance(),该方法返回一个Calendar类的子类对象
static Calendar getInstance()
使用默认时区和语言环境获得一个日历
使用了多态,用父类型接收子类对象
Calendar c=Calendar.getInstance();
public int get(int field)
:返回给定日历字段的值
public void set(int field,int value)
:将给定日历字段设置为给定值
public abstract void add(int field,int amout)
:根据日历的规则,为给定的日历字段添加或减去指定的时间量
public Date getTime()
:转换为Date类对象
public static long currentTimeMillis()
:返回以毫秒值为单位的当前时间public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
:将数组中指定的数据拷贝到另一个数组中。public StringBuilder()
:构造一个空的StringBuilder容器public StringBuilder(String str)
:构造一个StringBuilder容器,并将字符串添加进去public StringBuilder append(...)
:添加任意类型数据,并返回当前对象自身(可以链式编程)public String toString()
:将当前StringBuilder对象转换为String对象基本数据类型使用方便,效率高,但是缺少对应的方法来操作这些数据,故有时采用包装类。(除了char-Character和int-Integer,其他包装类都是首字母大写)
Integer(int i)
Integer(String s)
:其中s必须时基本类型字符串,否则抛出异常static Integer valueOf(int i)
:返回一个Integer实例static Integer valueOf(String s)
int intValue()
从JDK1.5开始,基本类型和包装类的装箱与拆箱可以自动完成
如ArrayList
ArrayListlist;
list.add(999); //自动装箱
int a=list[0]; //自动拆箱
总共三种方式
除了Character类以外,所有包装类都具有parseXxx静态方法,可以将字符串参数转换为对应的基本类型
public interface 接口名称{
接口内容
}
备注:换成了关键字interface后,编译生成的字节码文件仍然是.java->.class
实现类
(类似子类)来实现该接口public class 实现类名称 implements 接口名称{...}
public default 返回值类型 方法名称(参数列表){方法体}
public static 返回值类型 方法名称(参数列表){方法体}
private 返回值类型 方法名称(参数列表){方法体}
2.静态私有方法 :解决多个静态方法之间重复代码问题
private static 返回值类型 方法名称(参数列表){方法体}
public static final
三个修饰符(可以省略,但是不写也照样是这样,不能写别的),从效果上来说,这就是接口的常量*(final关键词修饰,说明不可改变)public static final 常量名称=数据值;
接口名称.常量
即可public class MyInterfaceImpl implements MyInterfaceA,MyInterfaceB{
//覆盖重写所有抽象方法
}
default
关键字不能省略父类名称 对象名=new 子类名称();
或者
接口名称 对象名称=new 实现类名称();
看new的是谁,就优先用谁,没有则向上找
父子都有,优先用子
成员方法:编译看左,运行看右
成员变量:编译看左,运行还看左
等号左边形式统一
Worker teacher=new Teacher();
Worker cooker=new Cooker();
teacher.work();
cooker.work();
对象的向上转型,其实就是多态写法
父类名称 对象名=new 子类名称()
含义:右侧创建一个子类对象,把它当作父类来看待使用
注意事项:向上转型一定是安全的
子类名称 对象名=(子类名称)父类对象
cat instanceof Cat
集合是JAVA提供的一种容器,可以存储多个数据
与数组的区别:
Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可以操作所有的单列集合
public boolean add(E e)
:给定对象添加到集合中public void clear()
:清空集合中所有元素public boolean remove(E e)
:把给定的对象在当前集合中删除public boolean contains(E e)
:判断当前集合中是否包含给定对象public boolean isEmpty()
:判断集合是否为空public int size()
:返回集合元素数量public Object[ ] toArray()
:把集合中的元素存储到数组中JDK中提供的专门用来遍历集合的接口(不是所有集合都有索引,即有些不能直接用for循环遍历)
迭代:即Collection集合元素通用的获取方式。取出元素前先判断集合中有没有元素,如果有则取出,再继续判断,一直到取完。这种取出方法的专业术语成为迭代
Iterator迭代器是一个接口,无法直接使用,需要接口的实现类对象。其获取实现类的方式特殊,Collection类中有一个方法叫iterator(),返回的就是Iterator的实现类对象
boolean hasNext()
:如果仍有元素可以迭代,返回true
E next()
:返回迭代的下一个元素
Collection<String>coll=new ArrayList<>();
coll.add("我爱你");
coll.add("中国");
coll.add("我爱你");
coll.add("塞北的雪");
Iterator<String>iter=coll.iterator();
while(iter.hasNext()){
System.out.print(iter.next());
}
或者
for(Iterator<String>iter=coll.iterator();iter.hasNext();){
System.out.print(iter.next());
}
增强for循环也称为for each循环,是JDK1.5以后出来的高级循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历中不能对集合中的元素进行增删操作。
//foreach遍历数组 (注意只能遍历,不能增删,因为其只是Iterator遍历的简化格式)
String[]arr={"我爱你","中国","亲爱的宝宝"};
for(String i:arr){
System.out.println(i);
}
//增强for循环遍历集合
Collection<Integer>coll=new ArrayList<>();
coll.add(1);
coll.add(2);
coll.add(3);
for(Integer i:coll){
System.out.println(i);
}
三个特点:1.有序 2.有索引 3.允许重复
public void add(int index,E element)
:将指定元素插入到指定位置public E get(int index)
:获取指定位置上的元素public E remove(int index)
:删除指定位置上的元素,并返回该元素public E set(int index,E element)
:用指定元素替换指定位置,并返回原来的元素底层是数组,查询快,增删慢。增加元素时需要创建一个比原来数组大1的新数组,再调用System.arraycopy将原有数组拷贝到新数组,效率低。因此开发中,增删用的多不建议使用ArrayList
特点:
常用方法
public void addFirst(E e)
public void addList(E e)
public E getFirst()
public E getLast()
public E removeFirst()
public E removeLast()
:等效于add方法public E pop()
:从此列表所表示的堆栈处弹出一个元素等效于removeFirstpublic void push(E e)
:将元素推入此列表所表示的堆栈 等效于addFirstpublic boolean isEmpty()
注意:获取元素时注意如果集合中没有元素,则会报错,需要用isEmpty先判断一下
单线程的,速度慢,JDK1.2后被ArrayList取代。了解即可
特点:
int hashCode()
返回该对象的哈希值public native int hashCode();
JDK1.8之前:哈希表=数组+链表
JDK1.8之后:哈希表=数组+链表/红黑树(提高查询速度)超过8个用红黑树
给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
LinkedHashSet继承了HashSet,底层是哈希表(数组+红黑树/链表)和一条链表(记录元素存储顺序),HashSet是无序的(不能保证存储和取出顺序一致),LinkedHashSet额外实现了有序(存储和取出顺序一致),也不允许重复
使用前提:
底层原理:可变参数底层是一个数组,根据传入参数个数会创建不同长度的数组
终极形式:object...obj
public static void main(String[] args) {
System.out.println(add(1,2));
System.out.println(add(1,2,3,4));
}
public static int add(int...arr){
int sum=0;
for(int i:arr){
sum+=i;
}
return sum;
}
java.utils.Collections
是集合工具类,用来对集合进行操作。部分方法如下:
public static boolean addAll(Collection c, T... elements)
:往集合中添加一些元素。public static void shuffle(List list) 打乱顺序
:打乱集合顺序。public static void sort(List list)
:将集合中元素按照默认规则排序。(使用前提,必须实现Comparable,重写接口中的compareTo方法/自己-目标是升序/)public static void sort(List list,Comparator )
:将集合中元素按照指定规则排序。import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
ArrayList<String>list=new ArrayList<>();
while(n-->0)
list.add(sc.next());
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int a=Integer.parseInt(o1+o2);
int b=Integer.parseInt(o2+o1);
if(a>=b)
return -1;
return 1;
}
});
StringBuilder sb=new StringBuilder();
for(String e:list)
sb.append(e);
System.out.println(sb);
}
}
特点:
继承了HashMap集合
特点:
特点:
public V put(K key, V value)
: 把指定的键与指定的值添加到Map集合中。public V remove(Object key)
: 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。public V get(Object key)
根据指定的键,在Map集合中获取对应的值。boolean containsKey(Object key)
判断集合中是否包含指定的键。public Set keySet()
: 获取Map集合中所有的键,存储到Set集合中。public Set> entrySet()
: 获取到Map集合中所有的键值对对象的集合(Set集合)。 Map<String,String> map=new HashMap<>();
map.put("大伯","大妈");
map.put("二伯","二妈");
map.put("老爸","老妈");
//利用keySet遍历Map
Set<String> set = map.keySet();
Iterator<String> iter = set.iterator();
while(iter.hasNext()){
System.out.println(map.get(iter.next()));
}
或者使用灵活版的foreach循环
for(String i:map.keySet()){
String value=map.get(i);
System.out.println(i+"和"+value);
}
键值对方式:即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。
操作步骤与图解:
获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。方法提示:entrySet()
。
遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。
通过键值对(Entry)对象,获取Entry对象中的键与值。 方法提示:getkey() getValue()
Map<String,Integer>map=new HashMap<>();
map.put("余丰旭",171);
map.put("陈香玉",160);
map.put("小小余",180);
//遍历Map的第二种方法,使用Entey键值对对象
//使用迭代器进行遍历
Set<Map.Entry<String, Integer>> set = map.entrySet();
Iterator<Map.Entry<String, Integer>> iter = set.iterator();
while(iter.hasNext()){
Map.Entry<String,Integer> entry=iter.next();
String key=entry.getKey();
Integer value=entry.getValue();
System.out.println(key+"身高是"+value+"厘米");
}
//使用增强for循环
for(Map.Entry<String,Integer> i:map.entrySet()){
System.out.println(i.getKey()+"身高为"+i.getValue()+"cm");
}
Map集合保证key是唯一的:作为key的元素,必须重写hashCode方法和equals方法,以保证key唯一
当我们不知道使用什么数据类型的时候,我们可以使用泛型。创建集合对象的时候就会确定泛型的数据类型
弊端:泛型是什么类型,就只能存储什么类型
定义了带泛型的类,创建对象时不写则默认为Object类
public class One<E> {
private E data;
public One() {
}
public One(E data) {
this.data = data;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
}
public static void main(String[] args) {
One<String>one=new One<>("使用了泛型");
System.out.println(one.getData());
One<Integer>two=new One<>();
two.setData(12);
System.out.println(two.getData());
}
含有泛型的方法,在调用方法时确定泛型的数据类型,传递什么类型的参数,泛型就是什么类型
格式:修饰符<泛型> 返回值类型 方法名(参数列表*(使用泛型)*){方法体}
定义格式:
修饰符 interface 接口名 <代表泛型的变量>{}
共有两种使用方式
public class Twoimplements MyInterface
用来表示暂时未知的类型
public class Demo {
public static void main(String[] args) {
ArrayList<Integer>list1=new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
ArrayList<String>list2=new ArrayList<>();
list2.add("我爱你");
list2.add("塞北的雪");
traverseList(list1);
traverseList(list2);
}
public static void traverseList(ArrayList<?>list){
/*for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}*/
//使用迭代器遍历
Iterator<?>iterator=list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
泛型的上限
类型名称 对象名称
只能接收该类型及子类型
类型名称 对象名称
只能接收该类型及其父类型
此时参数只能接收Person类及其子类对象
public static void func(Collection<? extends Person> coll)
此时参数只能接收Person类及其父类对象
public static void func(Collection<? super Person> coll)
```[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EKBUBlAi-1580906486394)(img\Collection与Map.bmp)]