- 概念:对象的容器,定义了对多个对象进行操作的常用方法,可实现数组的功能
与数组的区别:
- 数组长度固定,集合长度不固定
- 数组可以存储基本数据类型和引用类型,集合只能存储引用类型,当储存基本数据类型的时候会自动装箱
- 位置:java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test11 {
public static void main(String[] args) {
//todo 创建集合
Collection collection = new ArrayList();
//todo 添加元素
collection.add("chen");
collection.add("xing");
collection.add("en");
// 获取集合大小
System.out.println(collection.size());
//删除元素
collection.remove("chen");
System.out.println(collection.size());
//遍历集合
// todo 1.使用增强for循环遍历
for (Object o : collection) {
System.out.println(o);
}
// todo 2.使用迭代器
Iterator iterator = collection.iterator();
while (iterator.hasNext()){
Object o=iterator.next();
System.out.println(o);
//迭代器内不允许使用collection.remove();
//可以使用iterator.remove();
}
//todo 判断集合中是否有某元素
System.out.println(collection.contains("xin"));
System.out.println(collection.contains("xing"));
// todo 判断集合是否为null
System.out.println(collection.isEmpty());
// todo 清空集合
collection.clear();
System.out.println(collection.isEmpty());
}
}
特点:有序(添加顺序与遍历顺序)、有下标、元素可重复
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Test12 {
public static void main(String[] args) {
List objects = new ArrayList<>();
objects.add("chen");
objects.add("cx");
// todo 角标遍历
for (int i=0;i<objects.size();i++){
System.out.println(objects.get(i));
}
// todo 使用列表迭代器
ListIterator listIterator = objects.listIterator();
while(listIterator.hasNext()){
System.out.println(listIterator.nextIndex()+":"+listIterator.next());
}
//指针,所以必须先使用hasNext
while(listIterator.hasPrevious()){
System.out.println(listIterator.previousIndex()+":"+listIterator.previous());
}
//判断
System.out.println(objects.contains("chen"));
System.out.println(objects.isEmpty());
//获取位置
System.out.println(objects.indexOf("cx"));
}
}
import java.util.ArrayList;
import java.util.List;
public class Test13 {
public static void main(String[] args) {
List objects = new ArrayList<>();
//进行了自动装箱处理
objects.add(20);
objects.add(30);
System.out.println(objects.size());
//截取,含头不含尾
System.out.println(objects.subList(1,2));
//删除操作
objects.remove(0);
//objects.remove(20);此处是索引
System.out.println(objects);
objects.remove(new Integer(30));
System.out.println(objects);//[]
}
}
- ArrayList
1.数据结构实现,查询快,增删慢;
2.JDK1.2版本,运行效率快、线程不安全- Vector
1.数组结构实现,查询快、增删慢;
2.JDK1.0版本,运行效率慢、线程安全- LinkedList
1.链表结构实现,增删快,查询慢
创建ArrayList初始容量为0 ,当添加第一个元素时,容量变为10,扩容时,每次为前一次的1.5倍
public class Student implements Serializable {
private String name;
private String age;
public Student() {
}
public Student(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
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 name.equals(student.name) && age.equals(student.age);
}
//重写toString方法
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
public class Test14 {
public static void main(String[] args) {
ArrayList<Object> objects = new ArrayList<>();
objects.add(new Student("12","c"));
objects.add(new Student("12","x"));
System.out.println(objects);
//删除元素,此时需要重写equals方法,才能删除列表中的Student("12","c")
objects.remove(new Student("12","c"));
System.out.println(objects);
}
}
public class Test18 {
public static void main(String[] args) {
LinkedList<Object> objects = new LinkedList<>();
objects.add("c");
objects.add("x");
//迭代器遍历
Iterator<Object> iterator = objects.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
}
public class Test17 {
public static void main(String[] args) {
Vector<Object> objects = new Vector<>();
objects.add("c");
objects.add("x");
System.out.println(objects.size());
//遍历:使用枚举器
Enumeration<Object> elements = objects.elements();
while (elements.hasMoreElements()){
Object o = elements.nextElement();
System.out.println(o);
}
}
}
特点:无序(添加顺序与遍历顺序)、无下标、元素不可重复
- 基于HashCode实现元素不重复。
- 当存入元素的哈希码相同时,会调用equals进行确认,若结果为true,则拒绝后者存入
- 底层实际是用的HashMap
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Test21 {
public static void main(String[] args) {
Set<String> objects = new HashSet<String>();
objects.add("c");
objects.add("x");
System.out.println(objects.size());
//迭代器遍历
Iterator<String> iterator = objects.iterator();
while (iterator.hasNext()){
String next = iterator.next();
System.out.println(next);
}
boolean x = objects.contains("x");
System.out.println(x);
}
}
package com.utils;
import java.io.Serializable;
import java.util.Objects;
public class Student implements Serializable {
private String name;
private String age;
public Student() {
}
public Student(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
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 name.equals(student.name) && age.equals(student.age);
}
//重写toString方法
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
//重写hashcode
@Override
public int hashCode() {
//31 是一个质数,减少散列冲突,提高执行效率 31*i=(i<<5)-i
final int prime=31;
int result=1;
result=prime*result+((this.name==null)?0:(this.name.hashCode()));
result=prime*result+((this.age==null)?0:(this.age.hashCode()));
return result;
}
}
package com.utils;
import java.util.HashSet;
/**
* 存储结构:哈希表(数组+链表+红黑树)
* 存储过程:
* 根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步,
* 再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
*/
public class Test22 {
public static void main(String[] args) {
HashSet<Student> students = new HashSet<>();
Student student1 = new Student("c","1");
Student student2 = new Student("x","2");
students.add(student1);
students.add(student2);
//此时加不进来
students.add(new Student("x","2"));
System.out.println(students.toString());
}
}
- 基于排列顺序实现元素不重复
- 实现了SortedSet接口,对集合元素自动排序
- 元素对象的类型必须实现Comparable接口,指定排序规则
- 通过CompareTo方法确定是否为重复元素
package com.utils;
import java.io.Serializable;
import java.util.Objects;
public class Student implements Serializable,Comparable<Student>{
private String name;
private String age;
public Student() {
}
public Student(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
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 name.equals(student.name) && age.equals(student.age);
}
//重写toString方法
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
//重写hashcode
@Override
public int hashCode() {
//31 是一个质数,减少散列冲突,提高执行效率 31*i=(i<<5)-i
final int prime=31;
int result=1;
result=prime*result+((this.name==null)?0:(this.name.hashCode()));
result=prime*result+((this.age==null)?0:(this.age.hashCode()));
return result;
}
//按姓名比,再按年龄比
@Override
public int compareTo(Student o) {
int n1=this.getName().compareTo(o.getName());
int n2=this.getAge().compareTo(o.getAge());
return n1==0?n2:n1;
}
}
/**
* 存储结构:红黑树
* 要求:元素必须要实现Comparable接口
*/
public class Test23 {
public static void main(String[] args) {
TreeSet<Student> students = new TreeSet<Student>();
Student student4 = new Student("cx","3");
Student student1 = new Student("cx","1");
Student student2 = new Student("zx","3");
Student student3 = new Student("zx","2");
students.add(student1);
students.add(student2);
students.add(student3);
students.add(student4);
System.out.println(students.toString());
}
}
import java.util.Comparator;
import java.util.TreeSet;
/**
* Comparator实现定制比较
*/
public class Test24 {
public static void main(String[] args) {
//创建集合并指定比较规则
TreeSet<Student> students1 = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int n1=o1.getName().compareTo(o2.getName());
int n2=o2.getAge().compareTo(o2.getAge());
return n1==0?n2:n1;
}
});
//Student student4 = new Student("cxc","3");
//Student student1 = new Student("cxc","1");
Student student2 = new Student("zxz","3");
Student student3 = new Student("zxz","21");
//students.add(student1);
students1.add(student2);
students1.add(student3);
//students.add(student4);
System.out.println(students1.toString());
}
}
用于存储任意键值对(Key-Value),无序、无下标、键不允许重复(唯一),值可以
public class Test25 {
public static void main(String[] args) {
Map<String, String> stringStringHashMap = new HashMap<String, String>();
stringStringHashMap.put("cx","12");
stringStringHashMap.put("zx","13");
stringStringHashMap.put("vx","14");
//遍历keySet
Set<String> strings = stringStringHashMap.keySet();
for (String key : strings) {
System.out.println(key+":"+stringStringHashMap.get(key));
}
//entrySet
Set<Map.Entry<String, String>> entries = stringStringHashMap.entrySet();
for (Map.Entry<String, String> entry : entries) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
}
}
- 存储结构:哈希表
- 重复依据:键的hashCode()方法和equals()方法
- HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
- 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍,目的是减少调整元素的个数
- jdk 1.8 当每个链表长度大于8,并且数组元素个数大于等于64时,会调整成红黑树,目的提高执行效率
- jdk 1.8 当量表长度小于6时,调整成链表
- jdkv 1.8以前 链表是头插入,jdk1.8以后是尾插入
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//初始容量大小
static final int MAXIMUM_CAPACITY = 1 << 30;//数组最大容量
static final float DEFAULT_LOAD_FACTOR = 0.75f;//默认加载因子
static final int TREEIFY_THRESHOLD = 8;//JDK1.8 当链表长度大于8时,调整为红黑树
static final int UNTREEIFY_THRESHOLD = 6;//jdk1.8 当链表长度小于6,调整成链表
static final int MIN_TREEIFY_CAPACITY = 64;//jdk1.8 当链表长度大于8时,并且集合元素个数大于64,调整成红黑树
transient Node<K,V>[] table;//哈希表中的数组
实现了SortedMap接口(是Map的子接口),可以对key自动排序
存储接口:红黑树
如果key是实体类,那么该类需要实现Comparable接口,重写CompareTo方法
public class Test26 {
public static void main(String[] args) {
ArrayList<Integer> integers = new ArrayList<>();
integers.add(12);
integers.add(1);
integers.add(13);
//排序
Collections.sort(integers);
System.out.println(integers);
//binarySearch二分查找,找到了返回其所在的索引,否则返回一个小于0的数
int i = Collections.binarySearch(integers, 12);
int j = Collections.binarySearch(integers, 2);
System.out.println(i+":"+j);
//Copy复制
ArrayList<Integer> dest = new ArrayList<>();
//必须集合大小一致
for (Integer integer : integers) {
dest.add(0);
}
Collections.copy(dest,integers);
System.out.println(dest.toString());
//翻转排序
Collections.reverse(dest);
System.out.println(dest);
//打乱顺序
Collections.shuffle(dest);
System.out.println(dest);
//list转数组
Integer[] ts = dest.toArray(new Integer[dest.size()]);
System.out.println(Arrays.toString(ts));
//数组转list,但是是一个受限集合,不能使用list方法
List<Integer> integers1 = Arrays.asList(ts);
//integers1.add(2);
System.out.println(integers1);
}
}
- Java泛型是JDK1.5引入的一个新特性,其本质是参数化类型,把类型作为参数传递
- 常见形式泛型类、泛型接口、泛型方法。
- 语法 : <T,…> T称为类型占位符,表示一种引用类型。
- 好处:
- 提高代码的重用性
- 防止类型转换异常,提高代码的安全性
集合工具类,定义了除了存取以外的集合常用方法
/**
* 泛型类
* @param <T>
*/
public class Test19<T> {
//创建变量
T t;
//泛型作为方法参数
public void show(T t){
System.out.println(t);
}
//泛型作为方法返回值
public T getT(){
return t;
}
public static void main(String[] args) {
//泛型只能使用引用类型,不同泛型对象不能相互复制
Test19<String> stringTest19 = new Test19<>();
stringTest19.t="cxc";
stringTest19.show("cx");
System.out.println(stringTest19.getT());
}
}
/**
* 泛型接口
* 不能泛型静态常量
* @param <T>
*/
public interface Generics<T> {
String name="cx";
//T t;错误
T fun(T t);
}
package com.utils;
public class GenericsImpl<S> implements Generics<String>{
@Override
public String fun(String s) {
System.out.println(s);
return s;
}
}
class GenericsImpl2<T> implements Generics<T>{
@Override
public T fun(T t) {
System.out.println(t);
return t;
}
}
package com.utils;
public class Test20 {
public static void main(String[] args) {
GenericsImpl<String> generics = new GenericsImpl<String>();
generics.fun("cx");
GenericsImpl2<Integer> integerGenericsImpl2 = new GenericsImpl2<>();
integerGenericsImpl2.fun(1);
}
}
/**
* 泛型方法
* 语法: <T> 返回值类型
*/
public class MyGenerics {
//泛型方法
public <T> T show(T t){
System.out.println(t);
return t;
}
public static void main(String[] args) {
MyGenerics myGenerics = new MyGenerics();
myGenerics.show("cx");
myGenerics.show(12);
}
}
- 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致
- 特点:
- 编译时即可检查,而非运行时抛出异常
- 访问时,不必类型转换
- 不同泛型之间引用不能相互赋值,泛型不存在多态