欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

从零开始的java学习Day11----------基础篇(Java中的双列集合、泛型、可变类型)

程序员文章站 2022-05-28 15:00:52
...

Map集合

Collection中的集合称为单列集合,Map中的集合称为双列集合
Map中的集合,元素是成对存在的(理解为夫妻)。
每个元素由键与值两部分组成,通过键可以找到所对应的值。
注意:Map中的集合中键不可以重复,但值可以重复;每个键只能对应一个值。(如果添加元素时,键重复了,就会覆盖之前的键值对)

Map常用子类

HashMap<K,V>:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
LinkedHashMap<K,V>:HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
注意:这里的重写是指自定义类的,系统自带的例如:String,Integer就不需要重写

Map接口中的常用方法

put (K key, V value):                把指定的键与指定的值添加到Map集合中,如果添加的时候,键相同,则覆盖相同键的键值对
remove (Object key):                 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
get (Object key)                     根据指定的键,在Map集合中获取对应的值。
containsKey (Object key):           如果此映射包含指定键的映射关系,则返回 truecontainsValue(Object value):       如果此映射将一个或多个键映射到指定值,则返回 truesize():                            获取Map集合中键值对的个数
keySet():                           获取Map集合中所有的键,存储到Set集合中。
values():                           获取map集合中所有的值,存到collection集合
entrySet():                         获取到Map集合中所有的键值对对象的集合(Set集合)

上诉方法字面意思,都很简单,这里着重讲下下面两个方法:

keySet()

该方法可以获取整个Map集合对象里的key值,返回一个set集合的对象,该对象内存储的这个Map对象里的所有Key
格式:

对象名.keySet()          返回一个set对象,可以用现成的来接收,也可以new一个新的set对象来接收
entrySet()

该方法可以把Map对象里的所有键值对封装成一个个Map.Entry接口实现类的对象,再把这个Map.Entry对象存入一个set集合后返回
格式:

对象名.entrySet()        返回一个set对象,该set对象内装着一个个原Map集合里的键值对封装成的Map.Entry接口实现类对象
Map.Entry是Map接口的内部接口,该类中有方法
getKey():获取Entry对象中的键。
getValue():获取Entry对象中的值

遍历Map集合

想要遍历Map集合,有遍历该集合的键或者键值对两种方法
分别采用了上诉的keySet和entrySet方法
方法一:通过keySet方法得到该Map集合的Key(键)的Set集合,再遍历该set集合 ,得到每个Key,执行对象名.get(key)方法,得到该map集合的value(值)。
方法二:通过entrySet()方法得到该Map集合的键值对的set集合,再遍历该set集合,遍历执行Map.entry接口里的方法,getKey()和getValue分别得到键和值

HashMap

存储无序,哈希表结构

LinkedHashMap

存储有序,链表+哈希表结构
注意:他们两个都可以使用上述Map集合的方法,再次强调,如果是自定义的类的对象要存入Map集合,记得要重写hashCode和equals方法

JDK9对集合添加的优化

List,Set,Map,JDK9增加了静态of方法可以快速创建他们的对象,并赋值,但是需要注意的是,该对象创建后就不可以改变了(不能添加或者删除元素)
格式示例:

List<String> l =List.of("Aa","BB");               //创建了类型为List的l对象,并存入了"Aa"和"BB"字符串,下面两个以此类推
Set<String> s =Set.of("Aa","BB");                
Map<String,Integer> m =Map.of("Aa",1,"BB",2);

注意:
1:of()方法只是Map,List,Set这三个接口的静态方法,其父类接口和子类实现并没有这类方法,比如 HashSet,ArrayList等
2:返回的集合是不可变的

泛型

  • 泛型的意思其实就是一个位置的数据类型的意思一般用来表示,可以在类或方法中预支的使用未知的类型(实际处理参数时再给予具体类型,只支持引用数据类型)
  • 定义的时候加<>
  • 基本数据类型传入,会自动被装箱成他的包装类
  • 泛型没有继承和多态,不符合就是不符合
泛型的好处

1.可以降运行时期的错误,转移到编译时期(提示编译失败)
2.避免了类型强转的麻烦

泛型类(在类上定义泛型)

在定义类的时候,加上(E可以任意改变,里面再使用时前后对应就行),创建对象的时候,传入指定类型,类中使用时,就固定为该类型
整个类可以使用

格式:

public class 类名 <E>{
     private E e;
     public E fangFa1(E e){}
}   
//创建该对象的时候确定泛型的类型,例如这里传入String,那么该对象内的e就会是String对象,fanFa1的返回值类型和形参也会是String类型 

泛型方法(在方法上定义泛型)

类似泛型类,在定义方法的时候加上泛型,调用方法的时候,再确定泛型的类型
当前方法可以使用
格式:

public <E> E method(E e){
     return e;
}//此方法就使用了泛型,在调用方法时,传入的参数e是什么类型,返回值类型E也会跟着改变

泛型接口(在定义上定义泛型)

同泛型类,在定义接口时加上泛型。
格式:

public interface InteA <E>{
}//定义了一个泛型类,可以在接口中使用未知类型E
泛型接口有两个方式确定泛型的类型
  • 1.在定义实现类的时候,确定泛型类型
    格式:
public class Inet2A implements InteA<String>{
}这里就代表该接口在该实现类中的泛型类型为String
  • 2.在创建对象时,确定泛型类型
    格式:
public class Inte3A<E> implements InteA<E>{
}这里代表,创建该实现类的时候也不确定泛型类型,直到创建对象的时候再确定泛型的类型(注意,如果实现类实现接口时不写<>,则接口中使用的泛型类型为Object)

泛型的通配符

  • 当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
  • 在实际使用中,不知道使用什么类型来接收泛型的时候,此时可以使用?,?表示未知通配符。但是一旦使用?做类型传递,就不能再使用原对象的方法了(例如集合就不能再往里面存储数据了)。

通配符高级使用—受限泛型

之设置泛型的时候,没有加上限制,实际是任何类型都能接收,但是在Java中,泛型是可以指定一个泛型的上限和下限

泛型的上限:

格式:

类型名称 <? extends> 对象名称

意义: 只能接收该类型及其子类

泛型的下限:

格式:

类型名称 <? super> 对象名称

意义: 只能接收该类型及其父类型

可变参数

在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化成如下格式:

修饰符 返回值类型 方法名(参数类型... 形参名){  }

其实这个书写完全等价于:

修饰符 返回值类型 方法名(参数类型[] 形参名){  }

只是后面这种定义,你必须把参数先存进数组,再传递数组,而前面的,你直接传值进来,系统会自动封装成一个数组,在方法内使用的时候,还是当做一个数组使用
优势:不用创建数组
注意:如果方法有多个参数,参数中包含可变参数,可变参数一定要写在参数列表的末尾位置。

相关标签: 从零开始学java

上一篇: 关于Go 包管理

下一篇: go 内置函数