Java集合是使程序能够存储和操作元素不固定的一组数据。所有Java集合类都位于java.util包中
数组和集合的区别 :
数组 : 长度固定,可存放任意类型
集合 : 长度不固定, 不能存放基本数据类型,只能存放对象的引用
注意 : 如果集合存放基本数据类型,一定要将其"装箱"成对应"基本类型包装类"。
1.2继承体系由以上两图我们可以看出Java集合类有清晰的继承关系,有很多子接口和实现类。但是,并不是所有子接口或实现类都是最常用的。
最常用的几个子接口和实现类:
Collection---->List-------->ArrayList类
Collection---->List-------->linkedList类
Collection---->Set-------->HashSet类
Collection---->Set-------->SortedSet接口-------->TreeSet类
1.3常用方法 1.4使用方式package Collection;
import java.util.ArrayList;
import java.util.Collection;
public class Collection_01 {
public static void main(String[] args) {
// 创建集合对象
Collection c1 = new ArrayList();
c1.add(123);
// 1. 判断是否为空(集合中个数是否为0) true表示没有,false表示有
System.out.println(c1.isEmpty());
// 集合中是不能保存基本数据类型的(byte , int等等),需要转换为对应包装类才可以
// 这里会进行自动装箱操作,把基本数据类型转换成对应的包装类,
// 2. 添加操作 变量名.add(值);
// int-->Integer,然后发生多态转型为Object类型进行存储
// c1.add(123);
c1.add(new Integer(456));
// 因为所以的类都是Object的子类,所以添加操作里面可以加入任何类
// c1.add(new Collection_01());//打印的结果应该是他的地址
// 3.个数,集合中有几个元素,,变量名.size();
System.out.println(c1.size());
// System.out.println(c1.isEmpty());//判断集合是否为空
// 4. 删除,会调用要删除元素的equals方法,但是Integer覆写了,所以可以把 1 删掉
// c1.remove(456);
System.out.println(c1);
// 5. 把集合转换成数组 Objecr[] 数组名 = 集合变量面.toArray
Object[] arr = c1.toArray();
for (Object obj : arr) {
System.out.println(obj);
}
// 6. 清空集合 集合名.chear();
// c1.clear();
// 集合元素的个数
// System.out.println(c1.size());
A a =new A("张三");
A a1 = new A ("张三");
//把张三这个数组加入到c1这个集合当中
c1.add(a);
System.out.println(c1);
}
}
class A{
private String name;
public A(String name) {
super();
this.name = name;
}
//覆写hashCode和equals
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
//toString() 方法用于返回一个表示指定 char 值的 String 对象。
//结果是长度为 1 的字符串,仅由指定的 char 组成。
@Override
public String toString() {
return name ;
}
}
1.5注意Contains和remove
Contains(数据) : 判断集合中是否包含某个元素
Remove(数据 ) : 删除指定元素
两个方法底层都会自动调用该对象的equals方法
因为不管是判断是否包含还是删除,都要先找到这个数据,而找到只能比较
但是集合中保存的都是引用类型,所以比较只能使用equals方法
所以如果存储的是自定义类型,就要考虑equals方法的覆写问题
2. Iterator 2.1概述
在面向对象编程里,迭代器模式是一种设计模式,是一种最简单也是最常见的设计模式.
它可以让用户透过特定的接口寻访容器中的每一个元素而不用了解底层代码的实现.
获取该集合的迭代器对象
Iterator it = 集合对象.iterator ();
有三个方法 :
1. boolean hasNext() : 判断下面还有没有元素,如果有就返回true,没有就返回false
2. E next() : 获取下一个元素,并指向下一个元素
3. remove() : 删除当前指向的元素
三个方法的使用步骤,就是1,2,3 按照这个顺序调用
注意 : 迭代器一旦创建,集合中就不能添加和删除元素(长度不能更改了);如果添加或者删除了元素,那么迭代器必须重新生成
增强for循环, 就是为了让用iterator循环访问的方式简单,写起来更方便,
当然功能能不太全,比如删除,还是要用iterator来删除
public class Collection_02_Iterator {
public static void main(String[] args) {
Collection c1 = new linkedList();
c1.add(1);
c1.add("asd");
//集合变量名.contains(); 判断是否包含
System.out.println(c1.contains("asd"));
// 1 . 创建迭代器
Iterator it = c1.iterator();
// 遍历 判断下面是否有元素
//while循环,不用知道循环的次数是多少次
//终止条件为最后一个元素
//it.hasNext() 判断集合里是不是已经没有元素了
while (it.hasNext()){
//获取并指向下一个元素
Object obj = it.next();
System.out.println(obj);
}
//使用完一次后如果想要在使用一次迭代器,就必须要重新创建
it =c1.iterator();
//迭代器一旦创建之后,不能添加和删除,必须重新生成迭代器
c1.add(2);
c1.add(3);
c1.remove(1);
//因为这里发生了删除操作,如果不重新生成迭代器,就会报错,错误如下
//Exception in thread "main" java.util.ConcurrentModificationException
//at java.util.linkedList$ListItr.checkForComodification(linkedList.java:966)
//at java.util.linkedList$ListItr.next(linkedList.java:888)
//at Collection.Collection_02.main(Collection_02.java:53)
it = c1.iterator();
//重新构建的迭代器
while (it.hasNext()){
//获取并指向下一个元素
Object obj = it.next();
System.out.println(obj);
//asd 2 3
// c1.remove(obj);
//使用迭代器的时候,不能更改集合个数,所哟删除数据的时候不能使用集合的删除,应该使用迭代器的删除
it.remove();
//迭代器的删除方法,会删除迭代器中所有的元素
}
//打印输出迭代器中的元素的个数 迭代器变量民.size();
System.out.println(c1.size());
}
}
3. List
3.1概述
List特点 : 有序 可重复
有序 : 添加顺序和取出顺序是一致的
可重复 : 就是可以有重复的数据
ArrayList : 底层是个Object数组, 随机查询和更改效率高,随机添加和删除 效率低
linkedList : 底层是一个双向链表,随机查询更改效率低,随机添加和删除效率高
3.2ArrayListArrayList底层是数组,下标从0开始
默认初始化容量为10,扩大容量为原始容量的1.5倍
并且默认容量是第一次添加数据的时候设置的
也就是说 我们 new ArrayList()的时候,数组长度为0
1.5倍 : 长度+ 长度>>1;
3.2.1基本使用
public class Collection_03_List_01 {
public static void main(String[] args) {
// 创建对象
// Vector 已经过时了,ArrayList是Vector的升级版,Vector是线程安全,而ArrayList是非线程安全的
List list = new ArrayList();
list.add(100);
list.add(123);
// [100, 123] 覆写了toString方法
System.out.println(list);
}
}
3.2.2常用方法
package Collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Collection_04_List_02 {
public static void main(String[] args) {
//创建ArrayList对象
List list = new ArrayList();
//添加数据 这种方式添加的数据,数据在尾部
list.add(1);
list.add(2);
list.add(3);
list.add(4);
//add(E e) : 尾部添加
//add(int index, E e ): 添加到指定位置
//add(int index, E e ): 更改指定位置上的元素值
//remove(Object object) : 根据索引删除
//get( int index ): 获取指定位置的数据
list.add(1, 4);//指定位置添加数据
list.set(3, 33);//指定位置更改数据
System.out.println(list.get(3));//得到指定位置的数据
//这里是根据索引删除
//删除元素值为4
list.remove(4);
//删除元素值为1,这里是根据包装类引用删除
list.remove(new Integer(1));
System.out.println(list);
}
}
3.2.3遍历
//传统for遍历 for(int i=0; i3.3linkedList 3.3.1基本使用和方法 总结 : 和ArrayList操作 一模一样
public class Collection_06_linkedList_01 { public static void main(String[] args) { // 创建集合对象 linkedList list =new linkedList(); // List list = new linkedList(); // add(E e ) : 尾部添加 // add(int index , E e ) : 添加到指定位置 // set(int index, E e ) : 更改指定位置上的元素值 // remove(Object object) : 根据元素内容删除 // remove(int index) : 根据索引删除 // get(int index) : 获取指定位置的数据 // 首部添加 list.addFirst(1); // 首部添加 list.push(11); // 首部添加 成功返回true list.offerFirst(111); // 尾部添加 list.addLast(2); // 尾部添加 成功返回true list.offerLast(22); // 尾部添加 成功返回true list.offer(222); // 上面这几个方法 没啥区别,本质就是 linkLast 和 linkFirst list.add(1); list.add(2); list.add(3); list.add(0, 4); list.set(3, 33); System.out.println(list.get(2)); // 这是根据索引删除 list.remove(1); // 删除元素值为1 list.remove(new Integer(1)); System.out.println(list); // 传统for遍历 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } // foreach遍历 for (Object object : list) { System.out.println(object); } // 迭代器遍历 Iterator it = list.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } }3.3.2底层实现3.3.2.1 Node节点类
链表 : 保存的都是节点,一个节点有三个属性,添加数据,上一个节点引用,下一个节点引用
3.3.2.2 linkedList
3.3.2.3add方法实现
3.3.2.4Get方法实现
获取数据
Get方法 只是模拟了下标获取数据的方式,本质就是遍历,从头挨个去找
所以这可以理解为 并不是下标,只是决定了循环次数
而 ArrayList的get才是根据下标获取



