集合
一、Collection
1.集合
集合概述:
数组其实就是一个集合。集合实际上就是一个容器,可以用来容纳其他类型的数据。
2.集合和数组的区别
数组和集合类都是容器。
数组长度是固定的,集合长度是可变的。
数组中可以存储基本数据类型,集合只能存储对象
集合类的特点,用于存储对象,长度是可变的,可以存储不同类型的对象。
3.集合家族
二、Collection接口
1.增加
**add(E e);**将指定对象存储到容器中
**addAll(Collection<? extends E> c);**将指定容器元素添加到指定容器中
//增加add()将指定对象存储到容器中
Collection arr = new ArrayList();
arr.add("孙悟空");
arr.add("猪八戒");
arr.add("唐三藏");
arr.add("沙和尚");
System.out.println(arr);// [孙悟空, 猪八戒, 唐三藏, 沙和尚]
//addall(Collection<? extends E> c)将arr容器元素添加到arr2容器中
Collection arr2 = new ArrayList();
arr2.add("小白龙");
arr2.addAll(arr);
arr2.add("释迦摩尼");
System.out.println(arr2);// [小白龙, 孙悟空, 猪八戒, 唐三藏, 沙和尚, 释迦摩尼]
2.删除
**remove(Object o);**将指定元素从指定集合中删除
**removeAll(Collection<?> c);**将指定集合中的元素删除
//删除1.remove(Object o);将指定元素从指定数组中删除
boolean remove = arr2.remove("释迦摩尼");
System.out.println(remove);// true
System.out.println(arr2); // [小白龙, 孙悟空, 猪八戒, 唐三藏, 沙和尚]
//删除2.removeall(Collection<?> c); 将指定集合中的元素删除
boolean removeAll = arr2.removeAll(arr);
System.out.println(removeAll);// true
System.out.println(arr2);// [小白龙]
3.清空
**clear()**清空集合中的所有元素
//清除clear();清除一个集合中的所有元素
Collection arr = new ArrayList();
arr.add(1);
arr.add(2);
arr.add(3);
arr.add(5);
System.out.println(arr);//[1, 2, 3, 5]
arr.clear();
System.out.println(arr);//[]
4.判断
isEmpty();
contains(Object o);
containsAll(Collection<?> c);
Collection list = new ArrayList();
//增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);
//isEmpty();如果此集合不包含元素,则返回 true。
boolean empty = list.isEmpty();
System.out.println(empty);// false
//contains(Object o);如果此集合包含指定的元素,则返回 true。
boolean contains = list.contains("java编程思想");
System.out.println(contains);// true
Collection list2 = new ArrayList();
list2.add("水许传");
//containsAll(Collection<?> c);如果此集合包含指定集合中的所有元素,则返回 true。
boolean containsAll = list.containsAll(list2);
System.out.println(containsAll);// false
5.获取
**size();**返回指定集合中的元素数。
Collection arr = new ArrayList();
arr.add(1);
arr.add(2);
arr.add(3);
arr.add(5);
//返回指定集合中的元素数。
int size = arr.size();
System.out.println(size);//4
6.Collection接口的子接口
Collection接口有两个子接口:
List(链表|线性表)
Set(集合)
三、Set接口
1.HashSet
(1)HashSet结构和原理
元素的哈希值是通过元素的hashcode方法 来获取的, HashSet首先判断两个元素的哈希值,如果哈希值一样,接着会比较equals方法 如果 equls结果为true ,HashSet就视为同一个元素。如果equals 为false就不是同一个元素。
哈希值相同equals为false的元素是怎么存储呢,就是在同样的哈希值下顺延(可以认为哈希值相同的元素放在一个哈希桶中)。也就是哈希一样的存一列。
散列技术的原理:
把对象的主键直接用一个固定的公式计算,得出存储位置的方法。
优点是:可以快速命中搜索的目标。
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020090117062227.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NocjE5MTYxOTUwNjE=,size_16,color_FFFFFF,t_70#pic_center
(2)添加数据到HashSet
①基本数据类型存入HashSet中
HashSet hs = new HashSet();
hs.add(100);
hs.add(200);
hs.add(300);
hs.add(400);
hs.add(300);//数据重复不会存入
System.out.println(hs);//结果无序[400, 100, 200, 300]
②字符串类型数据存入HashSet中
HashSet hs = new HashSet();
hs.add("aaa");
hs.add("bbb");
hs.add("ccc");
hs.add("ddd");
hs.add("ccc");//数据重复不会存入
System.out.println(hs);//结果无序[aaa, ccc, bbb, ddd]
③自定义类型存入HashSet中
public static void main(String[] args) {
HashSet hs = new HashSet();
Student s1 = new Student("张三",20);
Student s2 = new Student("李四",21);
Student s3 = new Student("王五",23);
Student s4 = new Student("张三",20);
Student s5 = s1;
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
hs.add(s5);//s5和s1 指向同一个对象,所以hashCode相同,不会被存入
System.out.println(hs.size());
System.out.println(hs);
}
}
class Student{
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
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 "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
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;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
2.泛型(入门)
好处
增强程序的可读性和稳定性
Set <String> set = new HashSet <String>();
这个集合中就只能添加String类型的数据。
泛型:可以简单理解为限制了集合中存入的数据的类型。
3.迭代器和增强型for循环
(1)迭代器
Iterable接口:
Iterator iterator() 返回该集合的迭代器对象
Iterator接口定义的方法:
Itreator 该接口是集合的迭代器接口类,定义了常见的迭代方法
1:boolean hasNext()
判断集合中是否有元素,如果有元素可以迭代,就返回true。
2: E next()
返回迭代的下一个元素,注意: 如果没有下一个元素时,调用
next元素会抛出NoSuchElementException
3: void remove()
从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操
作)。
Set<String> set = new HashSet<String>();
set.add("aaa");
set.add("bbb");
set.add("ccc");
set.add("ddd");
Iterator<String> it = set.iterator();
/*
it.hasNext(); // 判断是否有下一个元素
it.next(); // 取到元素
*/
while(it.hasNext()){
String str = it.next();
System.out.println(str);
}
(2)增强型for循环
只要实现了Iterable接口的集合就可以使用增强型for循环进行遍历
Set<String> set = new HashSet<String>();
set.add("aaa");
set.add("bbb");
set.add("ccc");
set.add("ddd");
// 冒号前面写遍历后的类型 变量名
// 冒号后面写需要遍历的数组
for(String str:set){
System.out.println(str);
}
4.比较器
当Comparable比较方式,及Comparator比较方式同时存在,以Comparator
比较方式为主。
(1)comparable
compareTo 方法:this和参数的比较。
1、this-参数 升序
2、参数-this 降序
3、参数=this 重复数据
(2)comparator
compare方法比较规则:
1.前-后 升序
2.后-前 降序
3.前=后 重复数据
四、List接口
1.List中的方法
相对Collection接口扩展的方法有:
Object get(int index);
Object set(int index,Object element);
void add(int index,Object element);
Object remove(int index);
int indexOf(Object o);
int lastIndexOf(Object o);
2.ArrayList
ArrayList:实现原理:数组实现, 查找快, 增删慢
3.LinkedList
LinkedList:链表实现, 增删快, 查找慢
特有方法:
addFirst(E e)
addLast(E e)
getFirst()
getLast()
removeFirst()
removeLast()
如果集合中没有元素,获取或者删除元素抛:NoSuchElementException
4.ArrayList与LinkedList的区别?
他们都是线性表,但是ArrayList基于数组(顺序存储),LinkedList基于链表(链式存储)
由于实现的不同,ArrayList在随机访问元素时性能较高,插入和删除元素时效率较低,LinkedList则反之。
5.Vector
Vector: 描述的是一个线程安全的ArrayList。
ArrayList: 单线程效率高
Vector : 多线程安全的,所以效率低
特有的方法:
void addElement(E obj) 在集合末尾添加元素
E elementAt( int index) 返回指定角标的元素
Enumeration elements() 返回集合中的所有元素,封装到Enumeration对象中
Enumeration 接口:
boolean hasMoreElements()
测试此枚举是否包含更多的元素。
E nextElement()
如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素
五、Collections工具类
常用功能
List排序:sort方法
Collection元素搜索:binarySearch方法
改变Collection中的元素:addAll方法
int binarySearch(List list, E e ):在一个有升序顺序的List集合中,通过二分查找寻找元素e的索引
fill(List list, E e):将list集合中的所有元素都填充为元素e
int frequency(Collection c, E e):返回在集合c中的元素e的个数
max、min:获取集合的最大值或者最小值
replaceAll(List list, E oldVal, E newVal):将集合list中的所有指定老元素oldVal都替换成新元素newVal
reverse(List list):将参数集合list进行反转
shuffle(List list):将list集合中的元素进行随机置换
swap(List list, int a, int b):将a索引和b索引的元素进行交换
synchronizedXxx方法系列:将一个线程不安全的集合传入方法,返回一个线程安全的集合
栈(stack)
Stack类是Vector类的子类。特点是先进后出。
boolean empty() 测试堆栈是否为空。
E peek() 查看堆栈顶部的对象,但不从堆栈中移除它。
E pop() 移除堆栈顶部的对象,并返回该对象作为此函数的值。
E push(E item) 把项压入堆栈顶部。
int search(Object o) 返回对象在堆栈中的位置,以 1 为基数。