集合概述:
- 概念:对象的容器,定义了对多个对象进行操作的常用方法,可以实现数组的功能
- 和数组的区别:
- 数组长度固定,集合长度不固定
- 数组可以存储基本类型和引用类型,集合只能存储引用类型
- 位置:java.util.*
Collection体系:
Collection接口使用:
- 特点:代表一组任意类型对象,无序、无下标、不能重复
- 方法:
boolean add(Object obj) //添加一个对象。
boolean addAll(Collection c) //讲一个集合中的所有对象添加到此集合中。
void clear() //清空此集合中的所有对象。
boolean contains(Object o) //检查此集合中是否包含o对象。
boolean equals(Object o) //比较此集合是否与指定对象相等。
boolean isEmpty() //判断此集合是否为空。
boolean remove(Object o) //在此集合中移除o对象。
int size() //返回此集合中的元素个数。
Object[] toArray() //姜此集合转换成数组。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
//Collection接口使用1:
public class Demo01 {
public static void main(String[] args) {
//创建集合
Collection collection = new ArrayList();
//增加元素
collection.add("苹果");
collection.add("橘子");
collection.add("香蕉");
System.out.println("元素个数:"+collection.size());
System.out.println(collection);
//删除元素
/* collection.remove("香蕉");
System.out.println("元素个数:"+collection.size());
collection.clear();//清空
// System.out.println(collection);
System.out.println("删除之后:"+collection.size());*/
//遍历元素
//增强for循环
for (Object object : collection) {
System.out.println(object);
}
System.out.println("==========================");
//使用迭代器 专门用来遍历集合的一种方式
//hasnext 有没有下一个元素
//next 获取下一个元素
//remove 删除当前元素
Iterator it = collection.iterator();
while (it.hasNext()){
String s1 = (String) it.next();
System.out.println(s1);
// it.remove();//不能使用 collection.remove
}
System.out.println("元素个数:"+collection.size());
System.out.println("==========================");
//判断
System.out.println(collection.contains("橘子"));//判断是否存在橘子
System.out.println(collection.isEmpty());//判断是否为空
}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
//Collection接口使用2:
public class Demo02 {
public static void main(String[] args) {
Collection collection = new ArrayList();
Student s1 = new Student("张三",22);
Student s2 = new Student("李四",25);
Student s3 = new Student("王五",23);
//添加
collection.add(s1);
collection.add(s2);
collection.add(s3);
System.out.println("元素个数:"+collection.size());
System.out.println(collection.toString());
//删除
collection.remove(s3);
System.out.println("元素个数:"+collection.size());
System.out.println(collection.toString());
//遍历
for (Object object : collection){
Student s = (Student)object;
System.out.println(s);
}
Iterator it = collection.iterator();
while (it.hasNext()){
Student ss = (Student)it.next();
System.out.println(ss);
}
//判断
System.out.println(collection.contains(s1));
System.out.println(collection.isEmpty());
}
}
//学生类
public class Student {
private String name;
private int age;
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;
}
//重写toString方法
@Override
public String toString() {
return name+":"+age;
}
//重写equals方法
@Override
public boolean equals(Object obj) {
//判断是不是同一个对象
if (this==obj){
return true;
}
//判断是否为空
if (obj==null){
return false;
}
//判断是否是Student类型
if (obj instanceof Student){
Student s = (Student)obj;
//判断属性
if (this.name.equals(s.getName())&&this.age==s.getAge()){
return true;
}
}
return false;
}
}
List集合:
- 特点:有序、有下标、可以重复
- 方法:
void add(int index,Object o) //在index位置插入对象o。
boolean addAll(index,Collection c) //将一个集合中的元素添加到此集合中的index位置。
Object get(int index) //返回集合中指定位置的元素。
List subList(int fromIndex,int toIndex) //返回fromIndex和toIndex之间的集合元素。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class Demo03 {
public static void main(String[] args) {
//创建集合对象
List list = new ArrayList();
//添加元素
list.add("苹果");
list.add("橘子");
list.add("西瓜");
list.add(0,"香蕉");
System.out.println("元素个数:"+list.size());
System.out.println(list.toString());
//删除元素
//list.remove("苹果");
list.remove(0);
System.out.println("删除之后元素个数:"+list.size());
System.out.println(list.toString());
//遍历元素
//for循环
for (int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
System.out.println("==========================");
//增强for循环
for (Object object : list){
System.out.println(object);
}
System.out.println("===========================");
//迭代器
Iterator it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println("============================");
//使用列表迭代器,与Iterator的区别,ListIterator可以向前或向后遍历,添加、删除、修改元素
System.out.println("=====使用列表迭代器从前往后======");
ListIterator lit = list.listIterator();
while (lit.hasNext()){
System.out.println(lit.nextIndex()+":"+lit.next());
}
System.out.println("=====使用列表迭代器从后往前======");
while (lit.hasPrevious()){
System.out.println(lit.previousIndex()+":"+lit.previous());
}
//判断
System.out.println("=============================");
System.out.println(list.contains("苹果"));//判断是否存在
System.out.println(list.isEmpty());//判断是否为空
//获取位置
System.out.println("=============================");
System.out.println(list.indexOf("橘子"));
}
}
import java.util.ArrayList;
import java.util.List;
public class Demo04 {
public static void main(String[] args) {
//创建集合
List list = new ArrayList();
//添加数字数据 自动装箱
list.add(10);
list.add(20);
list.add(30);
list.add(40);
list.add(50);
System.out.println("元素个数:"+list.size());
System.out.println(list.toString());
System.out.println("=====================");
//删除操作
//list.remove(0);
list.remove((Object)10);
System.out.println("删除后:"+list.size());
System.out.println(list.toString());
System.out.println("======================");
//subList 返回子集合 含头不含尾
List subList = list.subList(1,3);
System.out.println(subList.toString());
}
}
List实现类:
ArrayList(重点)
- 数组结构实现,查询块、增删慢;
- JDK1.2版本,运行效率快、线程不安全。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class Demo06 {
public static void main(String[] args) {
//创建集合
ArrayList arrayList = new ArrayList();
//添加元素
Student s1 = new Student("张三",20);
Student s2 = new Student("李四",22);
Student s3 = new Student("王五",24);
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
System.out.println("元素个数:"+arrayList.size());
System.out.println(arrayList.toString());
//删除元素
//arrayList.remove(s1);
arrayList.remove(new Student("张三",20));//重写equals方法
System.out.println("删除之后:"+arrayList.size());
System.out.println(arrayList.toString());
//遍历元素
//增强for
System.out.println("=====增强for循环遍历=====");
for (Object object : arrayList){
Student s = (Student) object;
System.out.println(s);
}
//iterator 迭代器
System.out.println("=====iterator迭代器遍历=====");
Iterator it = arrayList.iterator();
while (it.hasNext()){
Student s = (Student) it.next();
System.out.println(s);
}
//Listiterator 列表迭代器
ListIterator lit = arrayList.listIterator();
System.out.println("=====从前往后=====");
while (lit.hasNext()){
Student s = (Student)lit.next();
System.out.println(s);
}
System.out.println("=====从后往前=====");
while (lit.hasPrevious()){
Student s = (Student) lit.previous();
System.out.println(s);
}
//判断
System.out.println(arrayList.contains(s2));//判断是否存在
System.out.println(arrayList.isEmpty());//判断是否为空
//查找
//System.out.println(arrayList.indexOf(s2));
System.out.println(arrayList.indexOf(new Student("李四",22)));//重写equals
}
}
Vector
- 数组结构实现,查询快、增删慢;
- JDK1.0版本,运行效率慢、线程安全。
import java.util.Enumeration;
import java.util.Vector;
public class Demo01 {
public static void main(String[] args) {
Vector v = new Vector();
v.add("草莓");
v.add("芒果");
v.add("西瓜");
//遍历
Enumeration en = v.elements();
while (en.hasMoreElements()){
String s = (String)en.nextElement();
System.out.println(s);
}
}
}
LinkedList
- 链表结构实现,增删快,查询慢。
import collection.Student;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
public class Demo01 {
public static void main(String[] args) {
LinkedList list = new LinkedList();
Student s1 = new Student("张三",20);
Student s2 = new Student("李四",22);
Student s3 = new Student("王五",24);
//增加
list.add(s1);
list.add(s2);
list.add(s3);
System.out.println("元素个数:"+list.size());
System.out.println(list.toString());
//删除
/*list.remove(s1);
list.remove(1);
System.out.println(list.toString());*/
//遍历
for (int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
System.out.println();
for (Object object : list){
Student s = (Student)object;
System.out.println(s);
}
System.out.println();
Iterator it = list.iterator();
while (it.hasNext()){
Student s = (Student)it.next();
System.out.println(s);
}
System.out.println();
ListIterator lit = list.listIterator();
while (lit.hasNext()){
Student s = (Student) lit.next();
System.out.println(s);
}
System.out.println();
while (lit.hasPrevious()){
Student s = (Student) lit.previous();
System.out.println(s);
}
}
}
ArrayList和LinkedList的区别
- ArrayList:必须开辟连续空间,查询快,增删慢。
- LinkedList:无需开辟连续空间,查询慢,增删快。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UK6R6QzE-1619101018910)(C:\Users\prioer\Desktop\febe000331d03d391696.png)]
泛型概述
- Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
- 常见形式有泛型类、泛型接口、泛型方法。
- 语法:
- <T,…> T称为类型占位符,表示一种引用类型。
- 好处:
- 提高代码的重用性。
- 防止类型转换异常,提高代码的安全性。
/**
* 泛型类
* 语法:类名<T>
* T是类型占位符,表示一种引用类型如果编写多个使用逗号隔开
*/
public class MyGeneric<T> {
//使用泛型T
//创建变量
T t;
//使用泛型作为参数
public void show(T t){
System.out.println(t);
}
//使用泛型作为方法返回值
public T getT(){
return t;
}
}
//泛型方法
public class MyGenericMethod {
public <T> T show(T t){
System.out.println("泛型方法:"+t);
return t;
}
}
/**
* 泛型接口
* 语法:接口名<T>
* 注意:不能创建静态常量
*/
public interface MyInterface<T> {
String name = "张三";
T server(T t);
}
public class TestGeneric {
public static void main(String[] args) {
//使用泛型类创建对象
//注意:泛型类只能使用引用对象,不同泛型类型对象之间不能相互赋值
MyGeneric<String> myGeneric = new MyGeneric<>();
myGeneric.t = "hello";
myGeneric.show("你好");
//String s = myGeneric.getT();
System.out.println(myGeneric.getT());
// MyGeneric<Integer> myGeneric1 = new MyGeneric();
// myGeneric1.t = 100;
// myGeneric1.show(500);
// Integer in = myGeneric1.getT();
// System.out.println(in);
//
// MyInterfaceImpl impl = new MyInterfaceImpl();
// impl.server("张三");
//
// MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>();
// impl2.server(10000000);
//
// MyGenericMethod myGenericMethod = new MyGenericMethod();
// myGenericMethod.show("张三");
// myGenericMethod.show(123);
}
}
import collection.Student;
import java.util.ArrayList;
import java.util.Iterator;
//泛型集合
public class Demo01 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("张三");
arrayList.add("李四");
arrayList.add("王五");
System.out.println(arrayList.toString());
for (String string : arrayList){
System.out.println(string);
}
ArrayList<Student> arrayList1 = new ArrayList<>();
Student s1 = new Student("张三",20);
Student s2 = new Student("李四",22);
Student s3 = new Student("王五",24);
arrayList1.add(s1);
arrayList1.add(s2);
arrayList1.add(s3);
Iterator<Student> it = arrayList1.iterator();
while (it.hasNext()){
Student s = it.next();
System.out.println(s);
}
}
}
Set集合
- 特点:无序、无下标、元素不可重复。
- 方法:全部继承自Collection中的方法。
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* Set接口的使用
* 特点:无序无下标 不能重复
*/
public class Demo01 {
public static void main(String[] args) {
Set<String> s = new HashSet<>();
//添加
s.add("苹果");
s.add("香蕉");
s.add("芒果");
System.out.println("数据个数:"+s.size());
System.out.println(s.toString());
//删除
// s.remove("苹果");
// System.out.println(s.toString());
//遍历
System.out.println("=====增强for=====");
for (String string : s){
System.out.println(string);
}
//迭代器
System.out.println("=====迭代器=====");
Iterator<String> it = s.iterator();
while (it.hasNext()){
String s1 = it.next();
System.out.println(s1);
}
//判断
System.out.println(s.contains("苹果"));
System.out.println(s.isEmpty());
}
}
Set实现类
HashSet【重点】
- 基于HashCode计算元素存放位置。
- 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。
import java.util.HashSet;
import java.util.Iterator;
/**
* HashSet的使用
* 存储结构:哈希表(数组+链表+红黑树)
* 存储过程:
* 1.根据hashCode计算保存位置,如果此位置为空,则直接保存,如果不为空执行第2步
* 2.在执行equals方法,如果equals方法为true,则认为是重复,否则形成链表
*/
public class Demo02 {
public static void main(String[] args) {
//创建集合
HashSet<Person> p = new HashSet<>();
Person p1 = new Person("张三",22);
Person p2 = new Person("李四",20);
Person p3 = new Person("王五",23);
//添加元素
p.add(p1);
p.add(p2);
p.add(p3);
p.add(new Person("刘德华",22));
System.out.println("元素个数:"+p.size());
System.out.println(p.toString());
//删除元素
// p.remove(p1);
// System.out.println(p.toString());
//遍历元素
for (Person person : p){
System.out.println(person);
}
Iterator<Person> it = p.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//判断
System.out.println(p.contains(p3));
System.out.println(p.isEmpty());
}
}
import java.util.Comparator;
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person(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 name+":"+age;
}
//重写hashCode
@Override
public int hashCode() {
int n1 = this.name.hashCode();
int n2 = this.age;
return n1+n2;
}
//重写equals
@Override
public boolean equals(Object obj) {
if (this==obj){
return true;
}
if (obj==null){
return false;
}
if (obj instanceof Person){
Person p = (Person)obj;
if (this.name.equals(p.getName())&&this.age==p.age){
return true;
}
}
return false;
}
//重写comparaTo
@Override
public int compareTo(Person o) {
int n1 = this.getName().compareTo(o.getName());
int n2 = this.age-o.getAge();
return n1==0?n2:n1;
}
}
/**
* 注意: hashSet存储过程:
* 根据hashCode计算保存的位置,如果位置为空,则直接保存,否则执行第二步。
* 执行equals方法,如果方法返回true,则认为是重复,拒绝存储,否则形成链表。
*/
TreeSet
- 基于排序顺序实现不重复。
- 实现了SortedSet接口,对集合元素自动排序。
- 元素对象的类型必须实现Comparable接口,指定排序规则。
- 通过CompareTo方法确定是否为重复元素。
import java.util.Iterator;
import java.util.TreeSet;
/**
* 使用TreeSet保存数据
* 存储结构:红黑树
* 要求:元素必须要使用Comparable接口
*/
public class Demo03 {
public static void main(String[] args) {
TreeSet<Person> treeSet = new TreeSet<>();
Person p1 = new Person("张三",20);
Person p2 = new Person("李四",21);
Person p3 = new Person("王五",23);
treeSet.add(p1);
treeSet.add(p2);
treeSet.add(p3);
System.out.println(treeSet.size());
System.out.println(treeSet.toString());
// treeSet.remove(p1);
// System.out.println(treeSet.toString());
//遍历
for (Person person : treeSet){
System.out.println(person);
}
Iterator iterator = treeSet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//判断
System.out.println(treeSet.contains(p1));
System.out.println(treeSet.isEmpty());
}
}
import java.util.Comparator;
import java.util.TreeSet;
/**
* TreeSet 集合的使用
* Comparator 实现定制比较(比较器)
* Comparable 可比较的
*/
public class Demo04 {
public static void main(String[] args) {
TreeSet<Person> personTreeSet = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int n1 = o1.getName().compareTo(o2.getName());
int n2 = o1.getAge()-o2.getAge();
return n1==0?n2:n1;
}
});
Person p1 = new Person("张三",20);
Person p2 = new Person("李四",21);
Person p3 = new Person("王五",23);
personTreeSet.add(p1);
personTreeSet.add(p2);
personTreeSet.add(p3);
System.out.println(personTreeSet.toString());
}
}
import java.util.Comparator;
import java.util.TreeSet;
/**
* TreeSet案例
* 使用TreeSet集合实现字符串按照长度进行排序
*/
public class Demo05 {
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n1 = o1.length()-o2.length();
int n2 = o1.compareTo(o2);
return n1==0?n2:n1;
}
});
treeSet.add("nanjing");
treeSet.add("dog");
treeSet.add("xiangjiao");
treeSet.add("English");
treeSet.add("pingguo");
System.out.println(treeSet.toString());
for (String string : treeSet){
System.out.println(string);
}
}
}
Map体系
- Map接口的特点:
- 用于存储任意键值对(Key-Value)。
- 键:无序、无下标、不允许重复(唯一)。
- 值:无序、无下标、允许重复。
Map集合概述
- 特点:存储一对数据(Key-Value),无序、无下标,键不可重复。
- 方法:
V put(K key,V value)
//将对象存入到集合中,关联键值。key重复则覆盖原值。
Object get(Object key)
//根据键获取相应的值。Set<K>
//返回所有的keyCollection<V> values()
//返回包含所有值的Collection集合。Set<Map.Entry<K,V>>
//键值匹配的set集合
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo01 {
public static void main(String[] args) {
//创建Map集合
Map<String, String> map = new HashMap<>();
//添加元素
map.put("cn", "中国");
map.put("uk", "英国");
map.put("usa", "美国");
System.out.println(map.toString());
//删除元素
// map.remove("usa");
// System.out.println(map.toString());
//遍历
//使用KeySet()
for (String key : map.keySet()) {
System.out.println(key + "=" + map.get(key));
}
//使用entrySet()方法
for (Map.Entry<String, String>entry: map.entrySet()){
System.out.println(entry.getKey()+"="+entry.getValue());
}
}
}
HashMap(重点)
存储结构:哈希表(数组+链表+红黑树)
使用key可使hashcode和equals作为重复
增、删、遍历、判断与上述一致
原码分析总结:
- HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16
- 当元素个数大于阈值(16*0.75 = 12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
- jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树,目的是提高效率
- jdk1.8 当链表长度 <6 时 调整成链表
- jdk1.8 以前,链表时头插入,之后为尾插入
Hashtable
线程安全,运行效率慢;不允许null作为key或是value
Properties
hashtable的子类,要求key和value都是string,通常用于配置文件的读取
TreeMap
实现了SortedMap接口(是map的子接口),可以对key自动排序
Collection工具类
概念:集合工具类,定义了除了存取以外的集合常用方法
直接二分查找int i = Collections.binarySearch(list, x);
成功返回索引
其他方法 : copy复制、reverse反转、shuffle打乱
补充:
// list转成数组
Integer[] arr = list.toArray(new Integer[10]);
sout(arr.length);
sout(Array.toString(arr));
// 数组转成集合
// 此时为受限集合,不能 添加和删除!
String[] name = {"张三","李四","王五"};
List<String> list2 = Arrays.asList(names);
// 把基本类型数组转为集合时,需要修改为包装类
Integer[] nums = {100, 200, 300, 400, 500};
List<Integer> list3 = Arrays.asList(nums);