集合
集合框架
// 集合框架
/* 1. collection : 存储一个人一个的数据
--------子接口 List: 存储有序的 可重复的数据
---------ArrayList(主要的实现类):线程不安全,效率高,底层用的Object[]数组储存
在添加数据,查找数据效率高 在插入 删除数据效率低
----------LinkedList :底层用的双向链表的方式储存 在对集合进行频繁 插入 删除 使用
在添加数据,查找数据效率低 在插入 删除数据效率高
----------Vector: List古老的实现类 线程安全,效率低,底层用的Object[]数组储存
---------子接口 Set : 存储无序的 不可重复的数据 常用方法 为Collection 声明的15个方法
-------------HashSet(主要的实现类) 使用数组 单向链表 红黑树 的结构进行存储 (要重写equals hashcode)
------------LinkedHashSet : HashSet的子类 使用数组 单向链表 红黑树 的基础上有添加了一组双向链表 (要重写equals hashcode)
用于记录添加元素的先后顺序 即按照添加元素的顺序进行遍历 便于频繁查寻
---------------TreeSet 底层使用红黑树的结构 按照添加元素的指定属性的大小进行遍历
2.Map : 存储一对一对的数据 (key--values 函数对应关系)
---------HashMap(主要的实现类) 线程不安全,效率高 可以添加null 的key和value的值 代码健壮性强 使用数组 单向链表 红黑树 的结构进行存储
--------------- LinkedHashMap: HashMap的子类在HashMap的数据结构基础上添加了个双向链表 用于记录添加元素的先后顺序,
// 进而在遍历的时候,按添加元素的顺序显示 开发中,对于遍历操作 建议使用此类
------------------TreeMap: 底层使用红黑树的结构 可以按照添加的key--values元素的指定的属性的大小顺序进行遍历 需要考虑自然排序和定制排序
------------------Hashtable:古老的实现类 线程安全,效率低,不可以添加null 的key或value的值 使用数组 单向链表 的结构进行存储
------------------Properties key--values元素都是String类型 常处理属性文件
HashMap元素的特点
1.HashMap中的所有的key彼此之间是不重复的,无序的所有的key构成一个Set集合 需要重写equals hashcode
2.HashMap中的所有的values彼此之间是可以重复的,无序的所有的key构成一个Collection集合 需要重写equals
3.HashMap中的key-values构成entry Hash Map中的entry彼此之间是无序的,不可重复的,所有的entry构成Set集合
*/
1. collection
Collection接口实现类的特点
public interface Collection extends Iterable
(1)Collection实现子类可以存放多个元素,每个元素可以是Object
(2)有些Collection的实现类,可以存放重复的元素,有些不可以
(3)有些Collection的实现类是有序的(List),有些是无序的(Set)–这里说的有序和无序是指取出的顺序是否和放入顺序一致
(4)Collection接口没有直接的实现子类,是通过它的子接口Set和List来实现的
collection的基本方法
增:add添加元素 addAll
删:.remove 删除指定的元素 remove(int index) 删除指定为位置的元素
改: set(int index,Object ele)
查:get(int index)
插: add(index ,Object ele) addAll(index ,Collection eles)
长度: size
遍历: 增强for循环 .Iterator 迭代器遍历集合元素
// 1.add添加元素 addAll size 长度
// ArrayList<Object> objects = new ArrayList<>();
Collection coll = new ArrayList();
coll.add("酷盖");
coll.add(520);
coll.add("奶盖");
coll.add(new Person ("奶盖",18));
System.out.println(coll);
Collection coll1= new ArrayList<>();
// coll1.add(1314);
// coll1.add(45);
coll1.add(520);
coll1.add(new Person ("奶盖",18));
// coll.addAll(coll1);
// System.out.println(coll +" " + coll.size()); //五个数据
//if 用add
// coll.add(coll1);
// System.out.println(coll.size() + " " + coll); // 四个数据 coll1 当成一个数据
//2.isEmpty 判断是否为空
System.out.println(coll.isEmpty());
//3.contains 判断有无该元素
System.out.println(coll.contains(520));
//4.containsAll 判断是不是该对象的子集
System.out.println(coll.containsAll(coll1)); // 注意如果有对象内容比较 要通过重写equals 方法
//5.void clear 清空元素
coll1.clear();
System.out.println(coll1);
//6.remove 删除指定的元素 remove(int index) 删除指定为位置的元素
coll.remove(520);
System.out.println(coll);
//7.removeAll(Collection coll)删除两个集合相同的元素
//8.retainAll(Collection coll)删除两个集合不相同的元素
//9.Object[] toString 返回当前集合所有元素的数组
Object[] array = coll.toArray();
System.out.println(Arrays.toString(array));
//10 Array.asList 数组转成集合
// int arr0[] = new int[] {1,2,4,5,};
String arr0 [] = {"1","2"};
Collection list = Arrays.asList(arr0);
System.out.println(list);
System.out.println("=============");
//11.Iterator 迭代器遍历集合元素 获取迭代器 coll(已创建的集合).iterator。var
// 实现遍历 while(iterator.hasNext()){ iterator.nest(); } 1.指针下移 2.下移后的集合元素返回
Iterator iterator = coll.iterator();
for(int i = 0;i < coll1.size();i++){
System.out.println(iterator.next());
}
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//错误写法
// while (iterator.next() != null){
// System.out.println(iterator.next());
// }
//12 增强for循环
//作用 遍历数组 集合 对于集合来讲 底层用的仍然是迭代器
for(Object obj : coll){ // 先写类型 再编写一个变量名 : 遍历的对象
System.out.println(obj);
}
// 增强for循环将元素依次赋给临时变量 注意 在循环体中对临时变量的修改,可能不会导致原有集合和数组的元组改变
/*
List:存储有序的 可重复的数据
List接口是Collection接口的子接口
(1)List集合类中元素有序(即添加顺序和取出顺序一致)、并且可以重复
(2)List集合中的每个元素都有其对应的顺序索引,即支持索引
(3)List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
(4)List接口的常用实现类有:ArrayList、LinkedList和Vector
—
//addAll 增填元素在某个位置
List list = new ArrayList(); //创建对象
list.add("奶盖");
list.add("520");
list.add("酷盖");
list.add(2,1314);
System.out.println(list);
List list1 = new ArrayList();
list1.add(1314);
list1.add(45);
list.addAll(3,list1); // 多个元素 不看做为一个整体
System.out.println(list);
List list2 = Arrays.asList(1,2,3);
list.add(3,list2); //*** add 当作一个整体
System.out.println(list);//[奶盖, 520, 1314, [1, 2, 3], 1314, 45, 酷盖]
list.addAll(3,list2);
System.out.println(list);//[奶盖, 520, 1314, 1, 2, 3, [1, 2, 3], 1314, 45, 酷盖]
list.remove(0); // 索引
System.out.println(list);
System.out.println(list.get(2));
list.remove( Integer.valueOf(2));// 删除对象2
System.out.println(list);
int i = list.indexOf(1); // 查找索引
System.out.println(i);
//遍历
Iterator iterator = list.iterator(); //创建对象
while (iterator.hasNext()){
System.out.println(iterator.next());
}
for (Object obj : list){
System.out.println(obj);
}
}
}
Set接口和常用方法
(1)无序(添加和取出的顺序不一致),没有索引
(2)不允许元素重复,所以最多包含一个null
(3)JDK API中Set接口的实现类有:
Set接口的遍历方式
同Collection的遍历方式一样,因为Set接口是Collection接口的子接口。
1.可以使用迭代器
2.增强for循环
3.不能使用索引的方式来获取
常用方法和list基本差不多
treeset
package Gather;
import java.util.Comparator;
import java.util.Objects;
public class TreeSet {
public static void main(String[] args) {
//TreeSet 底层使用红黑树的结构 按照添加元素的指定属性的大小进行遍历
// 要求: 添加的元素必须是同一类型的对象 否则会报错
//判断元素是否相同 不在考虑equals hashcode
//比较的标准是 自然排序 和定制排序 compareTo的返回值 如果返回值是0 则两个对象相等 返回第一个
// set.add("A");
// set.add("a");
// set.add("Z");
// set.add("J");
// set.add("P");
// set.add(1);
// java.util.TreeSet set = new java.util.TreeSet();// 无参自然排序
Comparator comparator = new Comparator() { // 定制排序******************************* // 比自然排序多样
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Student && o2 instanceof Student) {
Student student1 = (Student) o1;
Student student2 = (Student) o2;
int value = student1.getAge() - student2.getAge();
if (value != 0) {
return value;
} else
return student1.getName().compareTo(student2.getName());
}
throw new RuntimeException("输入异常");
}
};
java.util.TreeSet set = new java.util.TreeSet(comparator);// 有参定制排序
Student s1 = new Student("sam", 22);
Student s2 = new Student("sa", 18);
Student s3 = new Student("DaMing", 18);
Student s4 = new Student("jack", 23);
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
for (Object obj : set
) {
System.out.println(obj);
}
}
}
class Student implements Comparable {
private String name;
private int age;
public Student() {
}
public Student(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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
// @Override
// public boolean equals(Object object) {
// if (this == object) return true;
// if (object == null || getClass() != object.getClass()) return false;
// student student = (student) object;
// return age == student.age && Objects.equals(name, student.name);
// }
@Override
public int hashCode() {
return Objects.hash(name, age);
}
// @Override
public int compareTo(Object o) {//******************** 自然排序********************************************
if (this == o) {
return 0;
}
if (o instanceof Student) {
Student student = (Student) o;
int n = -(this.age - student.age); // 从大到小
if (n != 0) {
return n;
} else
return this.name.compareTo(((Student) o).name);
}
throw new RuntimeException("输入的类型错误");
}
}
2.Map
Map集合
Map接口实现类的特点
(1)Map与Collection并列存在,用于保存具有映射关系的数据Key-Value(双列元素)
(2)Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中
(3)Map中的key不允许重复,原因和HashSet一样,前面分析过源码。
(4)Map中的value可以重复
(5)Map的key可以为null,value也可以为null,注意key为null,只能有一个,value为null可以多个
(6)常用String类作为Map的key
(7)key和value之间存在单向一对一关系,即通过指定的key总能找到对应的value
(8)Map存放数据的key-value示意图,一对key-value 是放在一个Node中的,又因为Node实现了Entry接口,有些书上也说一对key-value就是一个Entry
// HashMap的方法
/*
增: put(Object key, Object values)
putAll(MAp m)
删: Object remove(Object key)
改: put((Object key, Object values)
putAll(MAp m) 覆盖
查: Object get(Object key)
长度: size
遍历:遍历key 集 Set keySet()
遍历values Collection values()
遍历entry Set entry()
*/
// 增
HashMap map = new HashMap();
HashMap map1 = new HashMap();
map.put(1,"8");
map.put("奶盖",23);
map.put("酷盖",22);
// map1.put("盖",23);
// map1.put("酷5盖",22);
// map.putAll(map1);
System.out.println(map);
// 删
map.remove(2);
System.out.println(map);
// 改
map.put("酷盖",45);
System.out.println(map);
// 查
map.get(1);
System.out.println(map.get(1));
// 遍历
Set keySet = map.keySet();
for (Object obj : keySet){
System.out.println(obj);
}
Collection values = map.values();
for (Object obj: values
) {
System.out.println(obj);
}
Set entry = map.entrySet();
for (Object obj: entry
) {
System.out.println(obj);
}
}
}
HashMap小结
Map接口的常用实现类:HashMap、Hashtable和Properties
HashMap是Map接口使用频率最高的实现类
HashMap是以key-value 对的方式来存储数据(HashMap$Node类型)
key不能重复,但是值可以重复,允许使用null值和null键(null键只能有1个)
如果添加相同的key,则会覆盖原来的key-val,等同于修改(key不会替换,val会替换)
与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的。
HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有synchronized