容器简介
- 用来容纳和管理数据
- 把容器里面的数据存储在内存而不是磁盘上。
int i=10;
其实i就是一个容器不过只能存储一个数据
下一步可以用数组来存储多个相同类型的数据,但是数据使用不灵活,要指定长度
容器的结构
单例集合
- 将数据一个一个的进行存储。
- list接口是有序存储,可重复,动态数组
- set接口,存储无序,不可重复,相当于集合
根接口collection接口(有两个子接口 list和set接口)
接口介绍
- Collection 是单例集合根接口,它是集中、收集的意思。Collection 接口的两个子接
口是 List、Set 接口。 - 由于 List、Set 是 Collection 的子接口,意味着所有 List、Set 的实现类都有下面的方法。
collection里面常用的抽象方法
子接口list接口
- 有序:有序(元素存入集合的顺序和取出的顺序一致)。List 中每个元素都有索引标记。可以根据元素的索引标记(在 List 中的位置)访问元素,从而精确控制这些元素。
- 可重复:List 允许加入重复的元素。更确切地讲,List 通常允许满足 e1.equals(e2) 的元素重复加入容器。
常用方法
- 除了collection里面的方法外还有一些方法
Arraylist容器类(list实现类)
- 是list的接口的实现类,是list存储特征的具体实现
- 底层是用数组实现的存储,特点:查询效率高,增删效率低,线程不安全。
package container;
import java.lang.ProcessBuilder.Redirect.Type;
import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
public static void main(String[] args) {
//实例化ArrayList容器
List<String> list = new ArrayList<>();
//添加元素 collection里面的add 返回一个Boolean
System.out.println(list.add("孙少聪"));
list.add(1, "oldlu"); //索引位置不能大于元素的个数,会导致下标越界
System.out.println(list);
//静态方法for循环遍历
ArrayListTest.bianli(list);
//删除元素
//根据索引删除E remove(int index)返回删除元素
System.out.println(list.remove(1));
//根据参数的值来删除对应的元素,有则删除返回true,无则返回false
System.out.println(list.remove("孙少聪"));
list.add("孙少聪");
list.add(1, "哈哈哈");
//替换元素 E set(int index,E elment)
//替换元素的位置一定要准确长度不能超过元素个数
list.set(1, "喜羊羊");
//清空容器
list.clear();
//判断容器是否为空
//isEmpty() 为空返回true不为空返回false
System.out.println(list.isEmpty());
//判断是否包含指定元素 Boolean contains(E elment)
System.out.println(list.contains("孙少聪"));
//查找失败返回-1
//查找元素第一次出现的位置
System.out.println(list.indexOf("孙少聪"));
//查找元素最后一次出现的位置
System.out.println(list.lastIndexOf("孙少聪"));
//将单例集合转换为数组
//将ArraList转换为Object[]
//但是不能将转换的数组做迁至类型转换
list.add("oldlu");
list.add("孙少聪");
Object[] arr = list.toArray();
for(int i = 0;i<arr.length;i++){
String str = (String)arr[i];
System.out.println(str);
}
//将单例集合转换为指定类型的数组
//但是类型需要参考泛型中的类型
String[] arr2 = list.toArray(new String[list.size()]);
for(int i = 0;i<arr.length;i++){
System.out.println(arr2[i]);
}
//容器并集操作
List<String> a = new ArrayList<>();
a.add("a");
a.add("b");
a.add("c");
a.add("f");
List<String> b = new ArrayList<>();
b.add("b");
b.add("c");
b.add("d");
boolean flag = a.addAll(b); //a已经被改变了
System.out.println(flag);
ArrayListTest.bianli(a);
//容器交集操作
boolean flag1 = a.retainAll(b);
System.out.println(flag1);
ArrayListTest.bianli(a);
//容器差集操作
boolean flag2 = a.removeAll(b);
System.out.println(flag2);
ArrayListTest.bianli(a);
}
//遍历容器中的元素
public static void bianli(List<String> list) {
//获取元素 E get(int index)
//list.size()方法获取list的元素个数
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i));
}
}
}
Vector容器类(list实现类)
- 线程安全,效率低
- 和ArrayList是相同的,都是list接口中的抽象方法做了具体实现
- 多了一个同步检查,将多个的并行的线程转换为串行
- 使用和ArrayList一样
package container;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
public class VectorTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> v = new Vector<>();
v.add("hjj");
v.add("ssc");
v.add("sjj");
v.get(1);
for (int i = 0; i < v.size(); i++) {
System.out.println(v.get(i));
}
}
}
Stack栈容器
- Vector的一个子类,实现标准的后进先出的栈LIFO
- 方法+小案例(判断符号对称性)
package container;
import java.util.Stack;
import java.util.Vector;
public class StackTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//实例化栈容器
Stack<String> lale = new Stack<>();
//将元素添加到栈容器中
lale.push("a");
lale.push("b");
lale.push("c");
//获取栈容器中的元素
//只能从栈顶取
String pop = lale.pop();
System.out.println(pop);
System.out.println(lale);
//判断栈里面是否为空,是true 否false
System.out.println(lale.empty());
//查看栈顶元素
System.out.println(lale.peek());
//返回元素在栈中的位置
System.out.println(lale.search("a")); //从顶往下数,栈顶是位置1
//判断对称性
StackTest stackTest = new StackTest();
stackTest.symmetry();
}
//匹配符号对称性
public void symmetry() {
String str="...{.....[....(....)...]....}..(....)..[...]...[...]";
//实例化Stack
Stack<String> a = new Stack<>();
//假设修正
boolean flag = true;
//拆分字符串抓取字符
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(c == '{') {
a.push("}");
}
if(c == '[') {
a.push("]");
}
if(c == '(') {
a.push(")");
}
if(c=='}' || c==']' || c==')') {
if(a.empty()) {
flag=false;
break;
}
String x = a.pop();
if(x.charAt(0) != c) {
flag = false;
break;
}
}
}
if(!a.empty()) {
flag = false;
}
System.out.println(flag);
}
}
LinkedList容器类(list实现类)
- 查询效率低,增删效率高,线程不安全
- 有序,允许重复
- LinkedList底层双向链表实现存储
- 查找只能从头查找,节点越多查找效率低
- 增删不涉及元素移动,直接挂载就行了。
package container;
import java.util.LinkedList;
import java.util.List;
public class LinkedListTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> list = new LinkedList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//遍历链表元素
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("==========================");
for (String str : list) {
System.out.println(str);
}
System.out.println("================LinkList+++++++++++++++++++++");
LinkedList<String> linkedList = new LinkedList<>();
linkedList.addFirst("a");
linkedList.addFirst("b");
linkedList.addFirst("c");
linkedList.addLast("a");
linkedList.addLast("b");
linkedList.addLast("c");
for (String str : linkedList) {
System.out.println(str); //c b a a b c
}
System.out.println(linkedList.getFirst()); //c
System.out.println(linkedList.getLast());//c
System.out.println(linkedList.removeFirst());//c
System.out.println(linkedList.removeLast());//c
}
}
子接口set接口
- 没有新增的方法,方法和Collection保持完全一致
- 无序,不重复
HashSet容器类(Set接口实现类)
- HashSet是一个没有重复的元素集合,不保证元素顺序。允许有null元素
- 底层采用Hash算法实现
- 线程不安全
package container;
import java.util.HashSet;
import java.util.Set;
public class HashSetTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<String> set = new HashSet<>();
//添加元素
set.add("ssc");
set.add("xjj");
set.add("hjj");
//获取元素
//set容器中没有索引,所以没有get方法
for (String string : set) {
System.out.println(string);
}
//删除元素
boolean flag = set.remove("ssc");
System.out.println(flag);
for (String string : set) {
System.out.println(string);
}
//大小
System.out.println(set.size());
}
}
HashSet存储自定义对象
- Users
package container;
import java.util.Objects;
public class Users {
private String username;
private int userage;
public void setUserage(int userage) {
this.userage = userage;
}
public int getUserage() {
return userage;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "Users{"+
"username='"+username+ '\'' +
", userage=" + userage +
'}';
}
public Users(String username, int userage) {
super();
this.username = username;
this.userage = userage;
}
public Users() {
super();
// TODO Auto-generated constructor stub
}
@Override
public int hashCode() {
return Objects.hash(userage, username);
}
@Override
public boolean equals(Object obj) {
System.out.println("equas........");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Users other = (Users) obj;
return userage == other.userage && Objects.equals(username, other.username);
}
}
- HashSetTest
package container;
import java.util.HashSet;
import java.util.Set;
public class HashSetTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<String> set = new HashSet<>();
//添加元素
set.add("ssc");
set.add("xjj");
set.add("hjj");
//获取元素
//set容器中没有索引,所以没有get方法
for (String string : set) {
System.out.println(string);
}
//删除元素
boolean flag = set.remove("ssc");
System.out.println(flag);
for (String string : set) {
System.out.println(string);
}
//大小
System.out.println(set.size());
System.out.println("====================自定义存储对象======================");
Set<Users> set1 = new HashSet<>();
Users u = new Users("oldlu", 18);
Users u1 = new Users("oldlu",18);
set1.add(u);
set1.add(u1);
//对比两个hashcode的值
//在User里面重定义了HashCode和equals方法了之后,两个hashcode的值就相同了
System.out.println(u.hashCode());
System.out.println(u1.hashCode());
for (Users users : set1) {
System.out.println(users);
}
}
}
TreeSet容器类(Set接口实现类)
- 可以对元素进行排序,不允许重复
- 底层是TreeMap实现的
- 排序实现方式:
通过元素自身实现比较规则
通过比较器比较规则
package container;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<String> set = new TreeSet<>();
set.add("c");
set.add("a");
set.add("b");
set.add("a");
set.add("d");
for (String string : set) {
System.out.println(string); // a b c
}
}
}
通过元素自身实现比较规则
- Users类
//自定义比较规则
//正数:大 负数:小 0:相等
@Override
public int compareTo(Users o) {
// TODO Auto-generated method stub
if(this.userage > o.userage) {
return 1;
}
return -1;
}
- TreeSetTest类
Set<Users> set1 = new TreeSet<>();
Users u = new Users("ssc", 22);
Users u1 = new Users("xjj", 20);
set1.add(u);
set1.add(u1);
//重写了compareto方法,在USers方法里面
for (Users users : set1) {
System.out.println(users);
}
通过比较器实现比较规则
- TreeSetTest类
System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++");
//直接将比较器作为参数穿给TreeSet
Set<Student> set2 = new TreeSet<>(new StudentComparator());
Student s = new Student("ssc", 11);
Student s1 = new Student("xjj", 10);
Student s2 = new Student("ajj", 10);
set2.add(s1);
set2.add(s);
set2.add(s2);
for (Student student : set2) {
System.out.println(student);
}
- Student类(类似Users类)
package container;
public class Student {
private String name;
private int 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 + "]";
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
}
- StudentComparetor类(比较器)
package container;
import java.util.Comparator;
public class StudentComparator implements Comparator<Student>{
//定义比较规则
@Override
public int compare(Student o1, Student o2) {
if(o1.getAge() > o2.getAge()){
return 1;
}
if(o1.getAge() == o2.getAge()) {
return o1.getName().compareTo(o2.getName());
}
return -1;
}
}
单例集合案例
- 例子用List和Set,创建一个1-10的随机数存储在容器中
- List
//产生一个[1,10]的随机数,并将10个随机数存在容器中
List<Integer> list = new ArrayList<>();
while(true) {
int num = (int)(Math.random()*10+1);
if(!list.contains(num)) {
list.add(num);
}
if(list.size()==10) {
break;
}
}
for (Integer integer : list) {
System.out.println(integer);
}
- Set
//产生一个[1,10]的随机数,并将10个随机数存在容器中
Set<Integer> set = new HashSet<>();
while(true) {
int num = (int)(Math.random()*10+1);
set.add(num);
if(set.size()==10) {
break;
}
}
for (Integer integer : set) {
System.out.println(integer);
}
双例集合
- 基于key和value的结构存储数据。
- 类似数学中的函数一个x对应一个。
与Collerction之间的区别
- Collection 中的容器,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。
- Map 中的容器,元素是成对存在的(理解为现代社会的夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。
- Collection 中的容器称为单列集合,Map 中的容器称为双列集合。
- Map 中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。
- Map 中常用的容器为 HashMap,TreeMap 等。
常用方法
HashMap容器类(Map接口的实现类)
- 底层采用了哈希表存储数据
- 要求键不能重复,如果发生重复,新的值会替换旧的值。
- HashMap 在查找、删除、修改方面都有非常高的效率。
package container;
import java.io.ObjectOutputStream.PutField;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.swing.plaf.synth.SynthScrollPaneUI;
public class HashMapTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
//添加元素 返回被替代的那个value值 键值相同的value会被覆盖
map.put("name", "孙少聪");
String value = map.put("name", "和佳佳");
System.out.println(value);
//获取元素方法一get
String val = map.get("name");
System.out.println(val);
//获取元素的方法二keySet
map.put("b", "B");
map.put("c", "C");
map.put("d", "D");
map.put("e", "E");
Set<String> keys = map.keySet();
for (String string : keys) {
String v1 = map.get(string);
System.out.println(v1);
}
System.out.println("================================================================");
//获取元素的方法三entrySet方法获取
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for (Map.Entry<String, String> entry : entrySet) {
String key = entry.getKey();
String v = entry.getValue();
System.out.println(key+"------"+v);
}
System.out.println("================================================================");
//并集操作 并过来的key相同那么原容器里面的Value会被覆盖掉
Map<String, String> map2 = new HashMap<>();
map2.put("f","F");
map2.putAll(map);
Set<String> keys2 = map2.keySet();
for (String key : keys2) {
System.out.println("key:"+key+"------"+"Value:"+map2.get(key));
}
System.out.println("================================================================");
//删除元素
String v = map.remove("e");
Set<String> keys3 = map.keySet();
for (String key : keys3) {
System.out.println("key:"+key+"------"+"Value:"+map.get(key));
}
System.out.println("================================================================");
//判断key或者Value是否存在
System.out.println(map.containsKey("aaaaa"));
System.out.println(map.containsKey("b"));
System.out.println(map.containsValue("B"));
}
}
TreeMap容器类(Map接口的实现类)
- TreeMap 和 HashMap 同样实现了 Map 接口,对于 API 的用法来说是没有区别的
- TreeMap 是可以对键进行排序的一种容器,在需要对键排序时可选用 TreeMap。
- TreeMap 底层是基于红黑树实现的
- 在使用 TreeMap 时需要给定排序规则:
- 元素自身实现比较规则
- 通过比较器实现比较规则
自身比较规则实现排序(Users类参考上面)
//自身比较规则实现比较
Map<Users,String> map = new TreeMap<>();
Users u1 = new Users("oldlu",18);
Users u2 = new Users("admin",22);
Users u3 = new Users("sxt",22);
map.put(u1, "oldlu");
map.put(u2, "admin");
map.put(u3, "sxt");
Set<Users> keys = map.keySet();
System.out.println(keys);
for(Users key :keys){
System.out.println(key+" --------- "+map.get(key));
}
外部比较器实现排序(Users类参考上面)
//外部比较器实现排序
Map<Student,String> treemap = new TreeMap<>(new StudentComparator());//传入外部比较规则
Student s1 = new Student("oldlu",18);
Student s2 = new Student("admin",22);
Student s3 = new Student("sxt",22);
treemap.put(s1, "oldlu");
treemap.put(s2, "admin");
treemap.put(s3, "sxt");
Set<Student> keys1 = treemap.keySet();
System.out.println(keys);
for(Student key :keys1){
System.out.println(key+" --------- "+treemap.get(key));
}
Iterator迭代器接口
- Collection接口继承了Iterable接口,在该接口中包含一个名为iterator的抽象方法,所有实现了Collection接口的容器类对该方法做了具体实现。
- iterator方法会返回一个Iterator接口类型的迭代器对象,在该对象中包含了三个方法用于实现对单例容器的迭代处理。
Iterator接口方法
boolean hasNext(); //判断游标当前位置是否有元素,如果有返回true,否则返
回false;
Object next(); //获取当前游标所在位置的元素,并将游标移动到下一个位置;
void remove(); //删除游标当前位置的元素,在执行完next后该操作只能执行
一次;
Iterator迭代List接口类型容器
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
//获取元素
Iterator<String> iterator = list.iterator();
System.out.println("=======================================================");
boolean flag = iterator.hasNext();
if(flag) {
String value = iterator.next();
System.out.println(value);
}
System.out.println("=======================================================");
//方式一:通过while循环
while(iterator.hasNext()) {
String value = iterator.next();
System.out.println(value);
}
System.out.println("=======================================================");
//方式二:for循环
for(Iterator<String> it = list.iterator();it.hasNext();) {
String value = it.next();
System.out.println(value);
}
Iterator迭代Set接口类型容器
Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
Iterator<String> iterator = set.iterator();
//方式一:while循环
while(iterator.hasNext()) {
String value = iterator.next();
System.out.println(value);
}
System.out.println("===============================================");
//方式二:while循环
for(Iterator<String> it = set.iterator();it.hasNext();) {
String value = it.next();
System.out.println(value);
}
Iterator迭代器删除元素
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
// int flag = -1;
// //不要在循环中改变他的长度,尽量在迭代过程中找到想要删除的元素记住他的下表,出来之后在删除
// for (int i = 0; i < list.size(); i++) {
// if("c".equals(list.get(i))) {
// list.remove(2);
// }
// System.out.println(list.get(i));
// }
for (String str : list) {
if("c".equals(str)) {
list.remove(str);
}
}
for (String str : list) {
System.out.println(str);
}
Collection工具类
- Collections 是一个工具类,它提供了对 Set、List、Map 进行排序、填充、查找元素的辅助方法。
- 该类中所有的方法都为静态方法。
Collection工具类常用方法
Collection排序和洗牌
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("d");
list.add("c");
//通过Collection方法进行排序
Collections.sort(list);
for (String str : list) {
System.out.println(str);
}
System.out.println("=====================================");
List<String> list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
list1.add("c");
list1.add("d");
//洗牌处理
Collections.shuffle(list1);
for (String str : list1) {
System.out.println(str);
}