Java的集合框架
Posted 情绪i
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java的集合框架相关的知识,希望对你有一定的参考价值。
Java集合框架综述
1:集合框架(Collection Framework)
首先要知道 集合代表的是一组对象,和数组差不多 但是数组的长度是固定不变的,而集合是可以变换长度的,比如说:集合就是一根金箍棒,可长可短, 数组就像是一根普通的木棍,长度是固定的,不能变长或者变短。在Java的集合框架中定义了一套规范用来操作集合和具体实现细节,在这里呢也可以把集合想象成一个数据库 ,它有“增删改查”四种操作 ,在本章呢会介绍集合框架的基本类和接口和一些的基本操作方法。
2:集合框架的两大接口(Collection和Map)
1.Collection接口
Collection表示一组对象 ,这些对象也称为collection元素,一个collection允许有重复的值,而另一些则不允许,一些collection是有序的,而有一些是无序的,在Java中没有直接实现collection的 但是它提供了两个子接口 这两个子接口继承了collection接口,那是哪两个接口呢?
ヾ(✿゚▽゚)ノ 这里介绍两个collection接口的子接口 List 和 Set
1.1ArraysLIst类
ArrayList是List的一个实现类。每一个ArrayList实例都有一个容量,该容量是指用来存储列表的数组大小,它总是等于或者小于列表的大小,随着向ArrayList不断添加元素,其容量也不断的增大。这里ArrayList它跟数组有很多相同点,到底有什么相同点和不同点呢?如下图
那知道ArrayList的概念 怎么创建一个ArrayList集合呢? 定义语法如下:
1 //创建ArrayList集合 2 List list = new ArraysList(0);
在创建ArrayList集合的时候需要导入包:
//导入包
import java.util.ArrayList; import java.util.List;
知道了创建ArrayList集合 那怎么向集合里添加元素呢 开始说过java集合框架中定义了一套规范来实现“增伤改查”那怎么实现具体操作呢?下面介绍ArrayList集合的常用方法:
ArraysLIst 集合的常用方法
Arrays.asList(); 将数组装换为集合
add(Object value); 添加元素
add(int index,Object value)向指定位置插入元素
get(int index);通过下标获取元素
set(intindex,Object value);修改指定位置的元素
remove(int index); 移除集合中指定位置的元素
remove(Object o);从集合中移除第一次出现的指定元素(如果存在)
removeAll(collection<?>c);从列表中移除制动的collection 中包含的所有元素
Clear (); 移除集合中所有的元素
//遍历ArrayList
foreach(Object item : list){
//通过get()方法获取元素
}
需要注意的是: 1.存储的元素类型都是Object类型
2.ArrayList集合中是可以添加重复的值,这个跟数组是一样的
3. 它的初始容量为10的空列表
1.2HashSet类
HashSet是一个哈希集是set的一个重要实现类 它不保证顺序恒久不变,也就是说是无序的,它允许使用NUll元素 但是只能有一个。而且他还不能有重复的值。set中 添加某个对象 无论添加多少次 最终只会保留一个该对象(的引用) 并且 保留的是第一次添加的那一个。既然是无序的所以它没有索引,不能通过索引获取元素。同样跟ArrayList一样它储存的类型也是Object类型。
那怎么创建一个Hashset呢? 代码如下:
//创建HashSet(哈希集)
HashSet hashset= new HashSet();
在创建HashSet实例时需要导入包:
import java.util.HashSet;
以下是HashSet类的一些常用方法 如下图:
add(Object value) 如果此 set中尚未包含指定元素,则添加指定元素 它的返回值是Boolean类型
clear() 移除所有元素
remove(Object o)如果指定元素存在于此 set 中,则将其移除 它的返回值是Boolean类型
size()获取set中的元素的数量 返回值是int
isEmpty()判断该set中是否包含任何元素 返回值是boolean类型
iterator() 返回对此 set 中元素进行迭代的迭代器。
大家看到Hashset并没有直接获取元素的方法,因为他是无序的 没有索引,这里我们用iterator()方法迭代获取数据,那怎么用呢?代码如下:
import java.util.Iterator;//导包
itIterator i = hash.iterator(); while(i.hasNext()){ String str = (String)i.next();//需要强转 }
这里需要注意的是 HashSet里储存是Object类型 需要什么数据类型 就强转成什么数据类型
上面的是通过Iterator()方法进行迭代 看起来比较麻烦 所以还有一种渐变的方法 通过foreach迭代器进行获取数据 代码如下:
foreach(Object item in hash){
//获取数据
}
上面是Collection接口中的两个子接口 List和Set 下面介绍另一个接口 Map
2.Map接口
Map提供了一种映射关系 其中的元素是以键值对(Key-value)的形式存储的 能够实现根据key快速查找Value
Map中的键值对以Entry类型的对象实例形式存在
健(key值)不可重复 value值可以
一个值可以跟很多的key进行映射关系 但一个健(key值)最多只能映射到一个值(value)
2.1 HashMap类
HashMap是map的一个重要实现,也是最常用的 基于哈希表实现 它的Entry对象是无序排序的,Key值和value值都可以为null 但是一个HashMap只能有一个kay值为null的映射(key值不可重复)
介绍了HashMap类的概念 那怎么创建呢? 代码如下:
//导入包
import java.util.HashMap;
//创建Hashmap
HashMap hash = new HashMap();
那HashMap类中有什么常用方法呢?如下:
get(Object key); 指定健获取所映射的值
Clear();从此映射中移除所有的映射关系
remove(Object key);从此映射中移除指定键的映射关系(如果存在)
size(); 获取此映射中的键-值映射的关系
put(K key,V value) 在此映射中关联指定的值与指定键 如果该映射以前包含了一个该键的映射关系 从而达到修改的功能
entrySet 语法: public Set<Map.Entry<K,V>> enttryset() 返回map中所有的键值对
KeySet 语法: public Ste<k>keyset() 返回此映射中所包含的键的set视图
getKey() 获取键
getValue() 获取值
如何向HashMap中添加映射关系呢?如下:
//创建HashMap
HashMap hashmap = new HashMap();
//通过HashMap类的Put()方法添加映射关系
hashmap.put(1, "张三");
这里需要注意的是:1.向HashMap中添加映射关系时 需要指定一个Key(键)指定一个Value(值)从而达到映射关系,
2.同样这里的健(key)和值(value)都是object类型,
如何获取HashMao中的数据呢?HashMap是键值对可以通过获取键的方法获取数据代码如下:
//通过HashMap类的gat(object key)获取值
System.out.println(hashmap.get(1));
那如何遍历HashMap中的元素呢? 用foreach迭代器实现 代码如下:
//遍历HashMap的Key值获取数据
for (Object item:hashmap.keySet()) {
System.out.println(hashmap.get(item));
}
其他的方法就不一一测试了 ( ̄▽ ̄)~*
那现在有一个问题 比如如下代码:
List list = new ArrayList();
list.add("qqyumidi");
list.add("corn");
list.add(100);
for (int i = 0; i < list.size(); i++) {
String name = (String) list.get(i); //1
System.out.println("name:" + name);
}
定义了一个List类型的集合,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时list默认的类型为Object类型。在之后的循环中,由于忘记了之前在list中也加入了Integer类型的值或其他编码原因,很容易出现类似于//1中的错误。因为编译阶段正常,而运行时会出现“java.lang.ClassCastException”异常。因此,导致此类错误编码过程中不易发现。
以上代码中有两个问题:
A.当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。
B.因此,//1处取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现“java.lang.ClassCastException”异常。
那有什么办法可以使集合能够约束元素类型呢 并达到安逸不报错呢?在Collection和Map中有出现了一个泛型集合。
3.什么是泛型?
泛型也可以理解为“参数化类型”,类型的参数化,就是可以把类型像方法的参数那样传递。这一点意义非凡。
那它有什么作用呢? :泛型使编译器可以在编译期间对类型进行检查以提高类型安全,减少运行时由于对象类型不匹配引发的异常。
怎么定义个泛型集合呢?把上面的代码修改如下:
List<String> list = new ArraysList<String>();//定义泛型的语法
list.add("aaa");
list.add("bbb");
list.add(1111);//1
foreach(String item : list){
System.out.println(item);
}
根据上面的代码 得到 定义泛型集合的语法:
List<E> list = new ArraysList<E>();
在List<>尖括号里是要对集合数据类型的约束
<E>中的E表示类型形参,可以接收具体的类型实参
上面的代码集合类型是String类型 那么代码“1”我们添加一个int类型的数据 这样编译器是会报错的,因为在定义泛型的时候 限制的是String类型 所以只能添加String类型的数据,
所以我们总结: 当泛型进行了数据类型约束的时候 不能添加其他的数据类型,否则编译器会报错。
那么HashSet也可以定义泛型,对元素的数据类型进行约束,那怎么创建HashSet泛型呢?语法如下:
//创建HashSet泛型
HashSet<E> hashSet = new HashSet<E>();
同样是对HashSet中的元素进行数据类型约束 用法如上,具体方法 请往上看HashSet集合的方法。
需要注意的是:
1.泛型集合中 不能添加泛型规定的类型及其子类型以外的对象 否则会报错
2.泛型集合中的限定类型 不能使用基本数据类型
3. 可以通过使用包装类限定允许存入的基本数据类型
以上是Collection家族的集合和泛型,那么Map家族有泛型吗? 答案是肯定的
HashMap如何定义泛型呢 我们用代码实现一下 代码如下:
//定义HashMap泛型
HashMap<K, V> Hashmap = new HashMap<K, V>();
在HashMap<K,V>
K代表的是Key(键)的数据类型,
V代表的值(value)的数据类型,
也就是说 K键的数据类型必须是规定的数据类型不能是其他的数据类型,值(value)也是一样。
以上是对泛型的介绍,这里在介绍一下Map中的contains方法:
contains方法 某个序列是否包含某个对象 如果包含则返回true 如果不包含则返回faslse
HashMap中:
ContainsKey(object key); 获取此映射是否包含对于指定建的映射关系
ContainsValue(object values); 获取此映射是否在此映射中存在的值
具体怎么使用呢?请看代码:
Student类
public class Student { //学号 private String id; //姓名 private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Student(String id,String name){ this.id=id; this.name=name; } }
test类
import java.util.HashMap;
/**
* ClassName: TestContains
* @Description: TODO测试 Map接口的HashMap类的Contains方法
*/
public class TestContains {
public static void main(String[] args) {
//创建HashMap泛型 键的类型约束是String类型 值的类型约束是学生类(Student)
HashMap<String, Student> hashmap = new HashMap<String, Student>();
//创建一个学生 张三
Student zs = new Student("A1000", "张三");
//向泛型中添加元素
hashmap.put("1",zs);
//检查是否存在键Key 1
boolean yesno = hashmap.containsKey("1");
//输出结果
System.out.println("Does it contain key1:"+yesno);
//检查是否包含值 Value “张三”这个学生
boolean yesno1 = hashmap.containsValue(zs);
//输出结果
System.out.println("Does it contain values‘张三’:"+yesno1);
}
}
这里我的HashMap中key的约束数据类型是String (这里大家注意下 泛型类型约束不能放基本数据类型 可以放数据类型的类 )value的类型约束是Student类的实例,也是就是说我定义的是学生类 里面只能放一个学生 要是放一个老师就不行。
言归正传 这里我使用HashMap中的Contains方法来判断泛型中是否包含某个键 或者包含某个对象,它的返回值类型就是Boolean类型,true或false;
接下来带大家认识两个接口和一个工具类:
1.Collections(工具类)
Collections工具类是java集合框架中 用来操作集合对象的工具类,这里我们只介绍一个方法sort();
在使用之前需要导入工具类的包 代码如下:
//导入包
import java.util.Collections;
sort()方法呢主要是排序 语法如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TetsCollectionsSort {
public static void main(String[] args) {
//创建ArrayList泛型
List<String> list = new ArrayList<String>();
//向集合里添加数据
list.add("aasd");
list.add("csfgsfd");
list.add("zasd");
list.add("gghg");
//输出排序前
System.out.println("排序前");
for (String item : list) {
System.out.println(item);
}
//进行排序
Collections.sort(list);
//排序后
System.out.println("排序后");
for (String item : list) {
System.out.println(item);
}
}
}
这里发现这些字符串的顺序发生了变化 那么是怎么进行排序的呢?
答:在排序String字符串的时候是比较首字母排序 如果首字母一样则比较第二个字符 如此往下,如果字符串的开头是数字,则比较数字的大小,数字在前,字母在后,
上面是java集合框架的Collections工具类的sort()方法的介绍,下面介绍一个接口
2.Comparable接口
前面介绍了Collections.sort()方法 而要实现序列的排序就要实现comparable接口下面就介绍Comparable接口
实现该接口表示,这个类的实例可以进行自然排序,
定义了默认的比较规则
其实现类需要compareTo()方法
compareTo()方法返回整数表示大 负数表示小 0表示相等
一个生活的小案例 在学校里做广播体操时 一般学生的排列都是按照身高去排列,从矮到高排列 因此学生是可以进行比较的,那么我们想两个事物要进行比较,是不是要找到可以比较的方式呢?在我们比较连个事物的时候
会有一个默认的比较规则,称为自然排序,比如在学生排列的时候这个身高就是可以比较的特性,也是默认的比较规则,那么自然顺序就是身高之间的差异。
那么如何用代码实现呢? 代码如下:
Student类
public class Student{ //学号 private String id; //姓名 private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Student(String id,String name){ this.id=id; this.name=name; } }
test类
import java.util.ArrayList; import java.util.List; import java.util.Collections; /* ClassName: TestContains * @Description: TODO测试comparable接口比较对象 */ public class TestContains { public static void main(String[] args) { // 创建HashMap泛型 键的类型约束是String类型 值的类型约束是学生类(Student) List<Student> list = new ArrayList<Student>(); // 创建两个学生 张三 李四 Student zs = new Student("Z1000", "张三"); Student ls = new Student("V1000", "李四"); // 向集合中添加元素 list.add(zs); list.add(ls); // 排列前 for (Student item : list) { System.out.println("学号是:" + item.getId() + "姓名:" + item.getName()); } // 排列 Collections.sort(list);//1 // 排序后 for (Student item : list) { System.out.println("学号是:" + item.getId() + "姓名:" + item.getName()); } } }
这里呢我们的代码1处会报错的 是因为咱们的Student这个类没有实现comparable接口 所以我们要对Student这个类进行改造 修改后的代码如下:
public class Student implements Comparable<Student>{ //学号 private String id; //姓名 private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Student(String id,String name){ this.id=id; this.name=name; } //重写comparable的comparato()方法 @Override public int compareTo(Student o) { return this.id.compareTo(o.id); } }
这里让Student这个类实现Comparable接口 因为接口都是抽象的 所以这里必须重写compareTo()方法
这个方法实现 让学生的Id进行一个比较排列 返回整形 那么Test类输出如下:
排序前
学号是:Z1000姓名:张三
学号是:V1000姓名:李四
排序后
学号是:V1000姓名:李四
学号是:Z1000姓名:张三
这里的排序方法向上面介Collections.sort()方法一样
3.Comparator接口 ---- 比较工具
用于定义临时比较规则,而不是默认比较规则
其实现类需要实现Compare()方法
强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法
compare()方法返回整数表示大 负数表示小 0表示相等
具体实现comparator接口的代码如下:
StudentComparator类
import java.util.Comparator; public class StudentComparator implements Comparator<Student>{
//要实现Comparator接口必须要重写Compare()方法 @Override public int compare(Student o1, Student o2) { //按照学生的姓名进行排列 return o1.getName().compareTo(o2.getName()); } }
Test类修改如下:
import java.util.ArrayList; import java.util.List; import java.util.Collections; /* ClassName: TestContains * @Description: TODO测试comparable接口比较对象和comparator接口 */ public class TestContains { public static void main(String[] args) { // 创建HashMap泛型 键的类型约束是String类型 值的类型约束是学生类(Student) List<Student> list = new ArrayList<Student>(); // 创建两个学生 张三 李四 Student zs = new Student("Z1000", "张三"); Student ls = new Student("V1000", "李四"); // 向集合中添加元素 list.add(zs); list.add(ls); // 排列前 System.out.println("排序前"); for (Student item : list) { System.out.println("学号是:" + item.getId() + "姓名:" + item.getName()); } // 排列 Collections.sort(list); // 排序后 System.out.println("排序后"); for (Student item : list) { System.out.println("学号是:" + item.getId() + "姓名:" + item.getName()); } //按照姓名排序如下 System.out.println("按照姓名排序是:"); Collections.sort(list,new StudentComparator()); for (Student item : list) { System.out.println("学号是:" + item.getId() + "姓名:" + item.getName()); } } }
这里Collections.sort();时需要传递一个集合 和一个实现类的对象,
本章主要介绍Java集合框架的主要成员有:Collection接口 Map接口 Collections工具类 Comparable接口 Comparator接口
本章内容到此结束!!!
以上是关于Java的集合框架的主要内容,如果未能解决你的问题,请参考以下文章