Collection集合
集合:集合是java中提供的⼀种容器,可以用来存储多个数据。
集合和数组既然都是容器,它们有啥区别呢?
1.数组的长度是固定的。集合的长度是可变的。
2.数组中存储的是同一类型的元素,可以存储基本数据类型值。
3.集合存储的都是对象。而且对象的类型可以不⼀致。
一般在开发中当对象多的时候,使用集合进行存储。
集合本身是一个工具,它存放在 java.util 包中。在 Collection 接口定义着单列集合框架中最最共性
的内容。
Collection方法
Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的⼀些方法,这些方法可用于操作所有的单列集合
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() | 返回集合中元素的个数。 |
package GatherDemo02;
import java.util.HashSet;
import java.util.Set;
public class HashSetDemo02 {
public static void main(String[] args) {
/*
* Set集合中的元素特点:唯一、无序
*/
//准备容器:创建HashSet对象
Set<String> set=new HashSet<String>();
//准备数据
String s1=new String("java");
String s2=s1;
String s3=new String ("java");
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set.size());//1
}
}
ArrayList常用方法:
方法名 | 说明 |
boolean add(Object o) | 在列表的末尾顺序添加元素,起始索引位置从0开始 |
void add(int index,Object o) | 在指定的索引位置添加元素。索引位置必须介于0和列表中元素个数之间 |
int size() | 返回列表中的元素个数 |
Object get(int index) | 返回指定索引位置处的元素。取出的元素是Object类型,使用前需要进行强制类型转换 |
boolean contains(Object o) | 判断列表中是否存在指定元素 |
boolean remove(Object o) | 从列表中删除元素 |
Object remove(int index) | 从列表中删除指定位置元素,起始索引位置从0开始 |
LinkedList常用方法:
方法名 | 说明 |
void addFirst(Object o) | 在列表的首部添加元素 |
void addLast(Object o) | 在列表的末尾添加元素 |
Object getFirst() | 返回列表中的第一个元素 |
Object getLast() | 返回列表中的最后一个元素 |
Object removeFirst() | 删除并返回列表中的第一个元素 |
Object removeLast() | 删除并返回列表中的最后一个元素 |
Iterator迭代器
Iterator接口:
在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了⼀个接口 java.util.Iterator。Iterator 接口也是Java集合中的⼀员,但它与 Collection、Map 接口有所不同, Collection 接口与 Map 接口主要用于存储元素,而 Iterator 主要用于迭代访问(即遍历) Collection 中的元素,因此 Iterator 对象也被称为迭代器。
获取迭代器的方法:
public Iterator iterator() :获取集合对应的迭代器,用来遍历集合中的元素。
迭代的概念:
迭代:即Collection集合元素的通用获取⽅式。在取元素之前先要判断集合中有没有元素,如果有, 就把这个元素取出来,继续在判断,如果还有就再取出出来。⼀直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
package GatherDemo03;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashMapDemo01 {
public static void main(String[] args) {
//准备容器:创建HashMap对象
HashMap<String, String> hm = new HashMap<String, String>();
//准备元素并将元素存储到集合中
hm.put("CN", "中华人民共和国");
hm.put("JP", "小日本");
hm.put("RU", "俄罗斯联邦");
hm.put("USA", "美利坚合众国");
hm.put("UK", "大不列颠及北爱尔兰联合王国");
System.out.println(hm.size());
//根据键获取对应的值
Object obj1=hm.get("CN");
String str1=(String)obj1;
System.out.println(str1);
System.out.println(hm.get("CNN"));
//删除集合中的元素
String str2=hm.remove("JP");
System.out.println(str2);
System.out.println(hm.size());//删除元素JP,还有4个元素
//获取HashMep集合中所有键值对的键
Set<String> keys=hm.keySet();
for (String key : keys) {
System.out.println(key);
}
//获取HashMep集合中所有键值对的值
Collection<String> values= hm.values();
for (String value : values) {
System.out.println(value);
}
//查询集合中是否存在指定键对应的键值对
System.out.println(hm.containsKey("RU"));//true
System.out.println(hm.containsKey("JP"));//false
//遍历键值对的3种方式
//方式一:获取键的集合,然后在遍历键的集合过程中调用get()方法获取值
Set<String> keys2 = hm.keySet();
for (String key : keys2) {
//根据键获取值
String value=hm.get(key);
System.out.println(key+"---"+value);
}
System.out.println("********************************");
//方式二:获取键的集合,然后在遍历键的集合过程中调用get()方法获取值
Set<String> keys3=hm.keySet();
Iterator<String> it = keys3.iterator();
while (it.hasNext()) {
String key = it.next();
//获得键
String value=hm.get(key);
System.out.println(key+"---"+value);
}
System.out.println("********************************");
//方式三:键值对遍历,将hm集合中的键值对整体取出来后放入到Set集合中
/*
*1)使用entrySet( )方法将hm集合中的键值对整体取出来放在Set集合中
*
*2)然后使用增强for循环或者迭代器取出Set集合中的键值对元素,取出来的
* 是Object类型,实际,上键值对的真正类型是Map. Entry类型
*
*3)所以将取出来的元素强制转换为Map. Entry类型,Map. Entry类中有getKey( )
* 方法获取键值对的键,有getValue( )方法获取键值对的值
*/
Set<Map.Entry<String,String>> keyValues=hm.entrySet();
for (Map.Entry<String,String> me : keyValues) {
//获取键
String key=me.getKey();
//根据键获取值
String value=me.getValue();
System.out.println(key+"---"+value);
}
}
}
package GatherDemo01;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class LinkedListDemo01 {
public static void main(String[] args) {
// 准备数据:创建5个NewsTitle类对象
NewsTitle nt1 = new NewsTitle(1001, "三亚新增本土480+774", "百度");
NewsTitle nt2 = new NewsTitle(1002, "中国成功发射一箭十六星", "中国航天");
NewsTitle nt3 = new NewsTitle(1003, "男子救落水5人后遇难 同伴讲述经过", "民间观察");
NewsTitle nt4 = new NewsTitle(1004, "苏氏祖祠:苏炳添是苏东坡第29代孙", "生活观察");
NewsTitle nt5 = new NewsTitle(1005, "家长花200万给娃集奥特曼卡没集齐", "合肥观察");
// 准备容器:创建集合对象,创建LinkedList对象
// List是一个接口,LinkedList是List接口的实现类,将List接口引用指向了实现类的实例,
// 向上转型:父类(接口)的引用指向子类的实例,父类引用无法调用子类特有的方法
List<NewsTitle> list = new LinkedList<NewsTitle>();
list.add(nt1);
list.add(nt3);
list.add(nt2);
list.add(nt2);
System.out.println(list.size());
//使用迭代器将list集合进行遍历
Iterator<NewsTitle> it =list.iterator();
while(it.hasNext()){
NewsTitle nt=it.next();
System.out.println(nt);
}
System.out.println("-------------------------");
//向下转型:子类的引用指向父类的对象 需要进行向下转型的原因是父类引用无法调用子类中特有的方法,子类特有的方法只能通过子类对象调用
LinkedList<NewsTitle> link = (LinkedList<NewsTitle>)list;
link.addFirst(nt5);
link.addLast(nt4);
for (NewsTitle object : link) {
System.out.println(object);
}
System.out.println("-------------------------");
//获取集合中的第一个元素和最后一个元素
System.out.println(link.getFirst());
System.out.println(link.getLast());
System.out.println("-------------------------");
//删除集合中的第一个元素和最后一个元素
link.removeFirst();
link.removeLast();
for (NewsTitle object : link) {
System.out.println(object);
}
}
}
Iterator接口的常用方法:
public E next() :返回迭代的下⼀个元素。
public boolean hasNext() :如果仍有元素可以迭代,则返回 true。
包装类的构造方法:
1)所有包装类都可将与之对应的基本数据类型作为参数,来构造它们的实例(对象)
2)除Character类外,其他包装类可将一个字符串作为参数构造它们的实例,Number类型包装类使用字符串作为参数构造实例的时候,字符串需要是能够转换为数字的字符串否则就会报NumberFormatException(数字格式化异常)
◆包装类把基本类型数据转换为对象
■每个基本类型在java.lang包中都有一 个相应的包装类
◆包装类的作用
■提供了一系列实用的方法
■集合不允许存放基本数据类型数据,存放数字时,要用包装类型
枚举类的使用:
例如:(类)
package GatherDemo06;
public enum Genders {
//枚举类是由一组固定的常量组成的类型
男,女,东方不败;
}
对象
package GatherDemo06;
public class Student {
public String name;
public Genders gender;
public static void main(String[] args) {
Student student = new Student();
student.name = "张三";
// student.gender = "男";
student.gender = Genders.男;
}
}
泛型的定义与使用
定义和使用含有泛型的类
将对象的类型作为参数,指定到其他类或者方法上,从而保证类型转换的安全性和稳定性
*本质是参数化类型*
泛型集合:
定义格式:
修饰符 class 类名 <代表泛型的变量> { }
例如,API中的ArrayList集合:
class ArrayList {
public boolean add(E e){ }
public E get(int index){ }
....
}
使用泛型: 即什么时候确定泛型
含有泛型的方法
定义格式:
修饰符 返回值类型 方法名(参数){ }
含有泛型的接口
定义格式:
修饰符 interface接口名 { }
泛型通配符:
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符表示。但是⼀旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
通配符高级使用 -- 受限泛型
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。
泛型的上限:
格式:类型名称 <? extends 类 > 对象名称
意义:只能接收该类型及其子类
泛型的下限:
格式: 类型名称 <? super 类 > 对象名称
意义: 只能接收该类型及其父类型