集合
一,集合基础简介
集合类: Collection(单列集合)是除了Map(双列集合)外所有的集合类的根接口
主要提供了三种集合 List , Set , Map
- List : 一种有序列表的集合
- Set : 一种保证没有重复元素的集合
- Map : 一种通过(key-value)键值对 查找的映射表集合
Java集合的特点:
- 实现了接口和类相分离 (一种类型的集合可以有多种不同的实现类)
- 支持泛型 (可以限制一个集合只存放一种元素)
- 集合的访问是通过迭代器实现的 (无需知道集合内部是按什么方式存储的)
集合和数组的区别:
- 集合长度可变
- 集合只能存储引用数据类型
- 集合可以存储不同数据类型(一般存储同一种)
二,Collection 集合
List 集合 (有序,可重复,有索引)
- 有序 : 数据存入的顺序和就是数据在集合的顺序
- 可重复 : 可以存入相同的数据
- 有索引 : 存入的数据可以通过索引读取
Set 集合 (无序,不可重复,无索引)
- 无序 : 数据存入的顺序和在集合中的顺序无关
- 不可重复 : 不能存入相同的数据
- 无索引 : 不能通过索引存取数据
Collection常用方法 [接口]
- 创建实现类对象
Collection<String> coll = new ArrayList<>();
- 添加元素 add()方法 成功return true否则return false Set类型的集合在存入重复值时返回false,存入失败
coll.add("aaa"); coll.add("bbb");
- 清空元素 clear()方法
coll.clear();
- 删除 remove() 成功
//因为Collection定义的是共性的方法,所以不能用索引 coll.remove("aaa");
- 判断当前的元素是否包含 contains(数据值) 利用equals方法判断是否存在,如果自定义类型,必须要在javabean类中重写equals方法
coll.contains("aaa");
- 判断集合是否为空 isEmpty()
coll.isEmpty();
- 获取长度 size()
coll.size();
迭代器遍历 Iterator (和集合专用的遍历方式,不依赖索引)
- 创建一个迭代器对象 (默认指向集合的0索引)
Iterator<String> it = list.iterator();
- 判断当前位置是否有元素 (有返回true,没有返回false)
boolean flag = it.hasNext();
- 获取当前元素,移动索引
String str = it.next();
- 循环获取所有的元素
while(it.hasNext){ String str = it.next(); System.out.println(str); }
增强For遍历
格式:
for(数据类型 s : 集合/数组){ }
- s 变量是第三方的,在循环时会依次遍历数组或集合中的数据
- 改变s,不会改变集合或者数组中的数据
lambda表达式遍历
格式:
// 重写forEach方法 coll.forEach(new Consumer<String>(){ @Override public void accept(String s){ System.out.println(s);//s表示每个元素 } });
简化:
coll.forEach(s->System.out.print(s));
三,List 集合
3.1 主要接口方法
创建集合
List<Integer> list = new ArrayList<>();
- 在末尾添加一个元素 add(元素值)
list.add(99999999);
- 在指定索引添加一个元素 add(索引,元素值)
list.add(4,5555555);
- 删除指定索引的元素 remove(索引)
list.remove(3);
- 删除某个元素 remove(元素值)
list.remove(new Integer(23));
- 获取指定索引元素 get(索引)
list.get(1)
- 获取链表大小 size()
list.size();
- 判断List是否包含某个指定元素 contains(元素值)
boolean b = list.contains(new Integer(123));
- 返回某个元素的索引,如果元素不存在就返回-1 indexOf(元素值)
int count = list.indexOf(new Integer(123));
遍历数组
- 利用for循环和get()方法
for(int i =0 ; i<list.size();i++){ System.out.println(list.get(i)); }
- 利用迭代器 Iterator的对象方法hasNext()判断是否由下一个元素,由next()返回下一个元素
for(Iterator<Integer> it = list.iterator();it.hasNext();){ int s = it.next(); System.out.println(s); }
3.2 ArrayList
ArrayList 实现了List接口 (一个可以动态修改的数组)
- 导入
import java.util.ArrayList
- 初始化
ArrayLister<泛型> 变量名 = new ArrayLister<>();
- 修改某个元素的值 set(索引,要修改为的值)
变量名.set(0,相同类型的数据);
- 对数字或者字母(单词和数字按首字母)进行排序 Collections中的sort()方法
1.先导包 import java.util.Collections; 2.调用方法 Collections.sort(集合名);
3.3 LinkedList 【🔺🔺🔺重要】
LinkedList 双链表,查询快,首尾操作快
- 导入
import java.util.LinkedList
- 初始化
1.普通创建方法 LinkedList<引用数据类型> list = new LinkedList<引用数据类型>(); 2.使用集合创建 Collection collection = new LinkedList(); collection.add("数据1");//可以存放任意数据类型 collection.add("数据2"); collection.add("数据3"); LinkedList list1 = new LinkedList(collection);
- 在头部添加元素 addFirst(数据值)
list1.addFirst("数据头部插入");
- 在尾部添加元素 addLast(数据值)
list1.addLast("数据尾部插入");
- 在列表开头移除元素 removeFirst()
list1.removeFirst();
- 在列表结尾移除元素 removeLast()
list1.removeLast();
- 获取列表尾部元素 getLast()
list1.getLast();
- 获取列表头部元素 getFirst()
list1.getFirst();
- 迭代元素
1.用size() for (int size = list1.size(), i = 0; i < size; i++) { System.out.println(list1.get(i)); } 2.用for-each for (String i : list1) { System.out.println(i); }
四,Set 集合
- 无序性 : 存取数据顺序不一致
- 不重复 : 存入的数据不能有相同的,利用特点可以去重
- 无索引 : 没有带索引的方法,不能使用索引遍历,不能使用普通for遍历
4.1 HashSet
- HashSet是利用哈希表储存数据的
- 如果存入的对象时自定义的,需要重写HashCode(使其转换时用属性值)和equals(比较时用属性值)
例子:
import java.util.HashSet; import java.util.Set; public class SetTest { public static void main(String[] args) { //创建Student对象 Student student = new Student("孙豪杰",19); Student student1 = new Student("孙浩杰",23); Student student2 = new Student("孙豪杰",19); Student student3 = new Student("孙浩杰",18); //创建集合用于添加学生对象 HashSet<Student> hashSet = new HashSet<>(); //添加元素 hashSet.add(student); hashSet.add(student1); hashSet.add(student2); hashSet.add(student3); //打印 System.out.println(hashSet); } }
Student类
import java.util.Objects; public class Student { String name; int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Student student = (Student) o; return age == student.age && Objects.equals(name, student.name); } @Override public int hashCode() { return Objects.hash(name, age); } /** * 获取 * @return name */ public String getName() { return name; } /** * 设置 * @param name */ public void setName(String name) { this.name = name; } /** * 获取 * @return age */ public int getAge() { return age; } /** * 设置 * @param age */ public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{name = " + name + ", age = " + age + "}"; } }
4.2 LinkedHashSet 有序*
保证数据的顺序 存取有序
4.3 TreeSet
可排序
数字时按照从小到大排列
字符,字符串是按照ASCII码表数字升序排列
自定义的排序规则
自定义的类实现comparable<E>接口,E为传入的类型 重写 compareTo()方法 在方法里写排列方式
TreeSet<Insteger> ts = new TreeSet<>(); ts.add(2); ts,add(5); ts.add(7);
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
HashMap最多允许一条记录的键为null
HashMap是无序的,不会记录插入的顺序
创建一个HashMap对象
HashMap<引用数据类型1, 引用数据类型2> Sites = new HashMap<引用数据类型1, 引用数据类型2>(); HashMap<Integer, String> hasdMap = new HashMap<Integer, String>();
- 添加元素 put(键值对);
hashMap.put(0,"a"); hashMap.put(1,"b"); hashMap.put(2,"c");
- 读取元素 get(键)访问对应的值
String str = hashMap.get(2) System.out.println(str); // c
- 删除元素 remove(键)
hashMap.remove(1); System.out.println(hashMap);//{0=a,2=c}
- 元素数量 size()
int i = hashMap.size(); System.out.println(i);// 2
- 迭代HashMap keySet()获取Key的值 values()获取valus的值
// 输出 key 和 value for (Integer i : hashMap.keySet()) { System.out.println("key: " + i + " value: " + hashMap.get(i)); } // 返回所有 value 值 for(String i: hashMap.values()) { // 输出每一个value System.out.println(i); // a c }
五,泛型
创建数据是<>内的数据类型
- 如果没有泛型就可以往集合内添加任意数据,默认为Object类型
- 弊端,多态原理,无法调用数据的每种类型的特有的方法
- 泛型中不能写基本数据类型,因为基本数据类型无法转为Object类型
- 传递数据可以传递泛型的子类
例子:
pubilc class ArrayList<E>{ Object[] ob = new Object[255]; int size; //定义传入的数据 E类型的数据e public boolean add(E e){ //存入ob类型 ob[size] = e; size++; return true; } //读取数据 public E get(int i){ E e = (E)ob[i]; return e; } //遍历 @Verride pubilc String toString(){ return Arrays.tosString(ob); } }
- 方法定义泛型 (适用于不确定方法内传什么数据)
public <T> void add(T t){ }
- 可变参数
public Static<E> void add(ArrayList<E>list, E...e){ for(E element : e){ list.add(element); } }
- 泛型接口
1.实现类给出具体类型 pubilc abstract class 类名 implements 接口名<String>{ } 2.实现类不确定具体类型 pubilc abstract class 类名 implements 接口名<E>{ }
六,Map (双列集合)
6.1 HashMap
HashMap 是一个散列表,它存储的内容是键值对(Key-value)映射
实现了Map接口,根据HashCode值存储数据
最多允许一条记录的键值为null (键值具有唯一性)
HashMap是无序的,不会记录插入的顺序
导包
import java.util.HashMap;
- 创建
HashMap<引用数据类型1,引用数据类型2> Sites = new HashMap<>();
- 添加元素
Sites.put(1,"asd");
- 访问元素
Sites.get(key);
- 删除元素
Sites.remove(key);
- 删除所有
Sites.clear();
- 计算大小
Sites.size();
- 迭代
//输出key和Sites for(数据类型1 i : Sites.keySet()){ System.out.println("Key:"+i+"Value:"+Sites.get(i)); } //输出所有value值 for(数据类型2 value : Sites.values()){ System.out.println(value+","); }