一:简单介绍
(1) 什么是集合
Java是面向对象的编程语言,对其描述事物都是通过对象来体现,因为万物皆对象,所以基本数据类型是不足以满足我们的需求,这时我们需要一个容器来实现我们的需求。
之前我们学过数组,但是数组的长度是固定的,很难适应多变的需求,那么有没有一种容器,可以存储对象,而且长度可变,操作方便呢?有的,那就是集合。
(2)集合和数组的对比
(3)集合框架介绍
分为 Collection 和 Map 两大类,Collection集合的子接口有Set、List、Queue三种子接口。我们比较常用的是Set、List,Map接口而不是collection的子接口
单列集合
双列
二 Collection集合
(1)collection简介
//add:添加单个元素
// collection.add("自导自演的悲剧");
// collection.add("陶喆");
// collection.add(true);
// System.out.println(collection);//[自导自演的悲剧, 陶喆, true]
// remove:
// 删除指定元素(只能删除指定元素,不能删除脚标)
//
// collection.remove(0);//[自导自演的悲剧, 陶喆, true]
// System.out.println(collection);
// ???为什么不是删除第一个元素
// collection父类方法只提供删除指定元素
//
// List list = new ArrayList();
// list.add("自导自演的悲剧");
// list.add("陶喆");
// list.add(true);
// list.remove(0);
// System.out.println(list);
//查找元素是否存在contains
// System.out.println(collection.contains("陶喆")); //true
//size:获取元素个数
// System.out.println(collection.size());//colleciton内容[自导自演的悲剧, 陶喆, true] 3
//isEmpty:判断是否为空
// System.out.println(collection.isEmpty());//false
//clear:清空
// collection.clear();
// System.out.println(collection);//[]
//addAll:添加多个元素
// 错误用法 collection.addAll("10:30 的飞机场","流沙","十七岁");,源码里给的参数是collection
// ArrayList arrayList=new ArrayList();
// arrayList.add("如果我真心爱你能否改变结局");
// arrayList.add("还是不懂珍惜");
// arrayList.add("还是搞砸一切");
// collection.addAll(arrayList);
// System.out.println(collection);//[自导自演的悲剧, 陶喆, true, 如果我真心爱你能否改变结局, 还是不懂珍惜, 还是搞砸一切]
//
//removeAll:删除多个元素
// collection.removeAll(collection);
// System.out.println(collection);//[]
(3)collection遍历方式
方式一:使用Iterator(迭代器)
简介:
执行原理:
单例集合数据存储结构如下:
我们通过构造一个迭代器,使用里面的next方法移动指针,从上到下(实际是从前往后,这里方便理解竖起来了)移动指针。
注意:在调用iteration.next()
方法之前必需调用iteration.hasNext()
进行检测
若不调用,且下一条记录无效,直接调用it.next()
会抛出NoSuchElementException
异常
代码如下:
Collection col = new ArrayList();
col.add(new demo("陶喆同名专辑", "陶喆", "1997-12-06"));
col.add(new demo("心中的日月", "王力宏", "2004-12-31"));
col.add(new demo("不可思议", "王力宏", "2003-10-15"));
System.out.println(col);
//第一种迭代器方式
Iterator iterator = col.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println(obj);
}
// 如果希望再次遍历,需要重置一下遍迭代器
iterator =col.iterator();
方法二:使用for循环增强
增强for循环,其实是简化版的iteration,本质是一样的底层依旧是迭代器,
只能遍历集合或数组
基本语法:
for(元素类型 元素名:集合名/数组名){
访问元素
}
代码如下:
//第二种,增强for循环
for(Object demo :col){
System.out.println(demo);
}
三:List接口
(1) 简介:
此接口可以对列表中每个元素的插入位置进行精确的控制,我们可以根据元素的整数索引(与数组的索引是一个道理)访问元素,并搜索列表中的元素。List 接口允许存放重复的元素,并且元素都是有序的(Set 接口不允许存放重复元素,元素是无序的)
集合中可以有重复的元素,可以通过 equals 方法来比较是否为重复的元素。
// ArrayList
四:Set集合
(1):简介:
注重独一无二的性质,该体系集合可以知道某物是否已近存在于集合中,不会存储重复的元素
用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复。
里面存储的是无序的不重复元素,没有索引,可以采用迭代器或增强for来获取元素。
(2):☆☆☆☆☆这里需要注意一下对象的相等性:
引用到堆上同一个对象的两个引用是相等的。
对两个引用调用hashCode方法,会得到相同的结果,如果对象所属的类没有覆盖Object的hashCode方法的话,hashCode会返回每个对象特有的序号(java是依据对象的内存地址计算出的此序号),所以两个不同的对象的hashCode值是不可能相等的。
如果想要让两个不同的Person对象视为相等的,就必须覆盖Object继下来的hashCode方法和equals方法,因为Object hashCode方法返回的是该对象的内存地址,所以必须重写hashCode方法,才能保证两个不同的对象具有相同的hashCode,同时也需要两个不同对象比较equals方法会返回true,两个条件都要满足。
例子:
没有重写hashCode和equals方法的前提下,set集合可以添加相同内容的对象,代码如下
public class HashSetPractice {
public static void main(String[] args) {
HashSet hashSet=new HashSet();
hashSet.add(new Employee("wang",18));
hashSet.add(new Employee("hao",18));
hashSet.add(new Employee("wang",18));
System.out.println(hashSet);
}
}
class Employee{
private String name;
private int age;
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
更改hashCode和Equals方法:
public class HashSetPractice {
public static void main(String[] args) {
HashSet hashSet=new HashSet();
hashSet.add(new Employee("wang",18));
hashSet.add(new Employee("hao",18));
hashSet.add(new Employee("wang",18));
System.out.println(hashSet);
}
}
class Employee{
private String name;
private int age;
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
if (age != employee.age) return false;
return name != null ? name.equals(employee.name) : employee.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
这里只是简单介绍一下Set这个接口,它的方法和List没有什么区别,list和set下面的实现类在后面的文章分享。