目录
一、集合概念
对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
位置:java.util.*;
数组长度固定,集合长度不固定。
数组可以存储基本类型和引用类型,集合只能存储引用类型。
int[] a Student[]
二、Collection体系集合
集合中只能放对象。
Collection体系集合 |
---|
Collections父接口:
特点:代表一组任意类型的对象,无序、无下标。
常用方法:
reverse//反转
shuffe//
sort//
binarySerach//
方法 | 描述 |
---|---|
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() | 将此集合转换成数组 |
注:遍历同时不能使用集合删除方法,否则出现并发修改异常,可使用迭代器的删除方法。
三、List接口与实现类【重点
】
3.1 List接口
特点:有序、有下标、元素可以重复。
继承Collection接口。
常用方法:
方法 | 描述 |
---|---|
void add(int index, Object o) | 在index位置插入对象o。 |
boolean addAll(int index, Collection c) | 将一个集合中的元素添加到此集合中的index位置。 |
Object get(int index) | 返回集合中指定位置的元素。 |
List subList(int fromIndex, int toIndex) | 返回fromIndex和toIndex之间的集合元素。 |
3.2 List实现类
3.2.1 ArrayList
List 名字 =new ArrayList();//什么都能装,但一般都是一种类型
get(下标)//获得元素;
add(int,字符串)//根据下标添加
set(int,)//指定下标跟新
集合.size||集合==nill //判断是否为空 []没东西也为空
数组结构实现,查询快、增删慢。
JDK1.2版本、线程不安全。
equalsp实现源码:
ArrayList的动态扩容机制:
elemntData.length : 长度
第一次添加数组:
扩容:
3.2.2 LinkedList
链表结构实现,增删快,查询慢。
JDK1.2版本、线程不安全。
add(索引,值);‘
remove(索引,值);????????
remove(index)//返回的是删除值
clear();//空间还在内容不要
set(索引,值);//修改
get(索引)//返回的是值
Arrays.asList(数组名)//数组转集合
ArrayList存储结构是数组,查找、遍历效率高。
LinkedList存储结构是双向链表,删除、添加效率高。
3.2.3 Vector(没人用)
add(); add(index,值);
remove(下标);
set(index,值);
size();get(index);
数组结构实现,查询快、增删慢。 JDK1.0版本,线程安全、运行效率比ArrayList较慢。
四、泛型
4.1 泛型概念
元素类型的限定:装的是同一类型的对象。
注意;泛型只支持引用数据类
概念:
Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
常见形式有泛型类、泛型接口、泛型方法。
语法:
<T,...> T称为类型占位符,表示一种引用类型。
优点:
提高代码的重用性。
防止类型转换异常,提高代码的安全性。
案例演示:创建泛型类。
1在类的上面:往对象上规定泛型
创建对像一定要规定类型
2在接口上:在接口上指定泛型,在实现类也得写与接口相同,在创建对象得指定具体类
3在方法上面:旨在方法上作用,指定传参的类型喝喝返回值类型
接口实现类HeroDaoImple: 演示三种用法
package com.qfedu.test01; import java.util.ArrayList; import java.util.List; /** * @Author lcw * @Description * @Date 2021/11/17 */ //1.泛型 :规范数据类型 <T> //2.第一种是往对象上规定泛型 //3.第二种在类上边写泛型,可以指定三个地方的类型: 属性 , 方法的返回值和方法的参数 //4.第三种用法在类上没有写,直接想在方法上写,: 参数传入的是什么类型,你给我返回什么类型 public class HeroDaoImpl<T> implements IHeroDao{ T a; public void sout(){ //打印a类型, Class aClass = a.getClass(); System.out.println(a.getClass().getName()); } public T aa(T b ) { return b; } // ctrl+i 实现接口:重写方法 ctrl+o 继承:重写方法 @Override public List selectAll() { //.1创建list对象 //List list = new ArrayList(); // 规定List中只能装 Hero对象, // List<T> list = new ArrayList<T>();// 后边的T可以省略 List<Hero> list = new ArrayList<Hero>(); //2.准备三个Hero对象 Hero h1 = new Hero("武大",1200); Hero h2 = new Hero("武二",10000); Hero h3 = new Hero("潘经理",100); Hero h4 = new Hero("西门xxx",100); //3.添加到list list.add(h1); list.add(h2); list.add(h3); list.add(h4); list.add(new Hero("王妈妈",1007)); /* Test01 t = new Test01(); list.add(h4);*/ return list; } }
//1.dao层对象 IHeroDao hd = new HeroDaoImpl(); List bb = hd.selectAll(); System.out.println(bb); HeroDaoImpl<String> hd2 = new HeroDaoImpl(); hd2.a ="1"; hd2.sout(); HeroDaoImpl<String> hd3 = new HeroDaoImpl();
单独演示:泛型方法。
public class Test01 { public <T> T aa(T t) { return t; } }
Test01 t = new Test01(); String aa = t.aa("123"); Hero aa1 = t.aa(new Hero()); int[] aa2 = t.aa(new int[1]);
案例演示:泛型接口。
package com.qfedu.test02; import java.util.List; /** * @Author lcw * @Description * @Date 2021/11/17 */ public interface IHeroDao<T> { public List<T> selectAll(); }
package com.qfedu.test02; import java.util.List; /** * @Author lcw * @Description * @Date 2021/11/17 */ public class HeroDaoImpl implements IHeroDao { @Override public List selectAll() { return null; } }
package com.qfedu.test02; import com.qfedu.test01.Hero; import java.util.List; /** * @Author lcw * @Description * @Date 2021/11/17 */ public class TMain { public static void main(String[] args) { IHeroDao<String> hd = new HeroDaoImpl(); List<String> strings = hd.selectAll(); } }
注:1、泛型只能使用引用类型。 2、不同泛型类型对象之间不能相互赋值。
4.2 泛型集合
参数化类型、类型安全的集合,强制集合元素的类型必须一致。
特点:
编译时即可检查,而非运行时抛出异常。
访问时,不必类型转换(拆箱)。
不同泛型之间引用不能相互赋值,泛型不存在多态。
public class TestArrayList2 { public static void main(String[] args) { ArrayList<String> arrayList=new ArrayList<String>(); arrayList.add("xxx"); arrayList.add("yyy"); // arrayList.add(10); // arrayList.add(20); for (String string : arrayList) { System.out.println(string); } ArrayList<Student> arrayList2=new ArrayList<Student>(); Student s1=new Student("刘德华", 20); Student s2=new Student("郭富城", 22); Student s3=new Student("梁朝伟", 18); arrayList2.add(s1); arrayList2.add(s2); arrayList2.add(s3); Iterator<Student> it=arrayList2.iterator(); while(it.hasNext()) { Student s=it.next(); System.out.println(s.toString()); } } }
五、Collections工具类
集合工具类,定义了除了存取以外的集合常用方法。
不用创建对象
常见方法:
方法 | 描述 |
---|---|
public static void reverse(List<?> list) | 反转集合中元素的顺序 |
public static void shuffle(List<?> list) | 随机重置集合元素的顺序 |
public static void sort(List<T> list) / | 升序排序(元素类型必须实现Comparable接口) |
public static <T> int binarySearch( list, T key) | 二分查找 |
package com.qfedu.test04; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; /** * @Author lcw * @Description * @Date 2021/11/17 */ public class Test01 { public static void main(String[] args) { //1.多态创建对象 List<Integer> list = new ArrayList<Integer>(); list.add(34); list.add(12); list.add(56); list.add(30); System.out.println(list); //1第一个方法反转 System.out.println("=====反转====="); Collections.reverse(list); System.out.println(list); //2. System.out.println("======随机重置 "); Collections.shuffle(list); System.out.println(list); //3.sort System.out.println("====sort排序"); Collections.sort(list); System.out.println(list); Collections.shuffle(list); //4. System.out.println("===二分查找"); Collections.sort(list); int i = Collections.binarySearch(list, new Integer(34)); System.out.println(list); System.out.println(i); } }
六、Set集合
6.1 Set接口
特点:无序、无下标、元素不可重复。
方法:全部继承自Collection中的方法。
使用foreach循环遍历: for(数据类型 局部变量 : 集合名){ //循环内部的局部变量,代表当次循环从集合中取出的对象 }
案例演示:使用Set接口保存数据。
6.2 Set实现类
6.2.1 HashSet
基于HashCode实现元素不重复。
当存入元素的哈希码相同时,会调用==或equals进行确认,结果为true,拒绝后者存入。
采用的哈希表(散列表) 数组 + 链表 + 树
案例演示:
package com.qfedu; /** * @Author lcw * @Description * @Date 2021/7/2 */ public class Hero { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "{" + "id=" + id + ", name='" + name + '\'' + '}'; } //判断两个对象是否相等重写equals方法 // hero对象.equals(hero对象) @Override public boolean equals(Object obj) { if(obj==null) { return false; } if(this==obj) { return true; } if(obj instanceof Hero) { Hero hero = (Hero)obj; if(this.getName().equals(hero.getName())) { return true; } } return false; } @Override public int hashCode() { return this.getId(); } }
-
[再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表。
6.2.2 LinkedHashSet
链表实现的HashSet,按照链表进行存储,即可保留元素的插入顺序。
6.2.3 TreeSet
基于排列顺序实现元素不重复。
实现了SortedSet接口,对集合元素自动排序。
元素对象的类型必须实现Comparable接口,指定排序规则(自然排序)。
通过CompareTo方法确定是否为重复元素。
案例演示:使用TreeSet保存对象数据。
package com.qfedu; import java.lang.ref.PhantomReference; import java.util.SortedSet; /** * @Author lcw * @Description 用来测试TreeeSet * * @Date 2021/7/2 */ public class Hero1 implements Comparable<Hero1>{ private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "{" + "id=" + id + ", name='" + name + '\'' + '}'; } //定义排序规则 hero.compareTO(hero) //比较两个对象是否相乖,如果相等,返回0 大于返回1 小于返回-1 @Override public int compareTo(Hero1 o) { // 我的主键 > 你的主键 if(this.getId() > o.getId()) { return 1; }else if(this.getId() < o.getId()) {// 我的主键 < 你的主键 return -1; } return 0; } }
package com.qfedu; import java.util.Comparator; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; /** * @Author lcw * @Description * @Date 2021/7/2 */ public class Test3 { public static void main(String[] args) { //1.创建TreeSet TreeSet<Hero1> set = new TreeSet<Hero1>(); //2.创建Hero1对象 Hero1 hero1 = new Hero1(); hero1.setId(132); hero1.setName("甄姬"); Hero1 hero2 = new Hero1(); hero2.setId(127); hero2.setName("马可波罗"); Hero1 hero3 = new Hero1(); hero3.setId(110); hero3.setName("甄姬"); set.add(hero1); set.add(hero2); set.add(hero3); for (Hero1 hero11 : set) { System.out.println(hero11); } } }
注:元素必须要实现Comparable接口,compareTo()方法返回值为0,认为是重复元素。
Comparator接口:
比较器,实现定制比较。
compare(o1,o2)方法的返回值0,表示重复。
案例演示:比较器的使用。
package com.qfedu; import java.util.Comparator; import java.util.TreeSet; /** * @Author lcw * @Description 利用比较器重新定义比较的规则 * @Date 2021/7/2 */ public class Test4 { public static void main(String[] args) { //TreeSet实例 的时候,重写比较方法 匿名内部类对象 //定义规则 0 == 1 > -1 < //创建比较器对象 Comparator<Hero1> comparator = new Comparator<Hero1>() { @Override public int compare(Hero1 o1, Hero1 o2) { //比较这两个对象 o1 o2 == null if (o1.getId() > o2.getId()) { return 1; } else if (o1.getId() < o2.getId()) { return -1; } return 0; } }; TreeSet<Hero1> set = new TreeSet(comparator); //2.创建Hero1对象 Hero1 hero1 = new Hero1(); hero1.setId(132); hero1.setName("甄姬"); Hero1 hero2 = new Hero1(); hero2.setId(127); hero2.setName("马可波罗"); Hero1 hero3 = new Hero1(); hero3.setId(110); hero3.setName("甄姬"); set.add(hero1); set.add(hero2); set.add(hero3); for (Hero1 hero11 : set) { System.out.println(hero11); } } }
七、Map集合
Map集合 |
---|
Map接口的特点:
用于存储任意键值对(Key-Value)。
键:无下标、不可以重复(唯一)。
值:无下标、可以重复 。
7.1 Map接口
特点:
称为“映射”存储一对数据(Key-Value),键不可重复,值可以重复。
常用方法:
方法名 | 描述 |
---|---|
V put(K key,V value) | 将对象存入到集合中,关联键值。key重复则覆盖原值。 |
Object get(Object key) | 根据键获取对应的值。 |
Set<K> keySet() | 返回所有key。 |
Collection<V> values() | 返回包含所有值的Collection集合。 |
Set<Map.Entry<K,V>> entrySet() | 键值匹配的Set集合。 |
7.2 Map实现类
7.2.1 HashMap【重点
】
JDK1.2版本,线程不安全,运行效率快。
允许用null 作为key或是value。
存储结构:哈希表。
put//可以进行增加也可以修改
remove(Key)//对建进行删除
get()//查找
案例演示:HashMap保存对象数据。
遍历
1 先用keySet()方法获取键的集合;再用循环,用get()方法获取对应的键
2先用entrySet()获取所有的键值对集合里面装的是Map.Entry(键,值);再用循环获取键值对的entry对象,分别用对象.getKey和getValue()获取键和值
package com.qfedu.map; import com.qfedu.list.Course; import com.qfedu.list.Stduent; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Author lcw * @Description * @Date 2021/11/18 */ public class Test01 { public static void main(String[] args) { //1.创建map 对象 key, value // 1001 张三 // 1002 李四 // 1003 王五 Map a = new HashMap(); //增 // key 键 唯一的 // value值 a.put(1001,"张三"); a.put(1002,"李四"); a.put(1003,"王五"); System.out.println(a); System.out.println("=======里边有多少个元素"); System.out.println(a.size()); System.out.println("=====泛型"); // 泛型 Map<Integer,String> map = new HashMap<>(); map.put(1001,"张三"); map.put(1002,"李四"); map.put(1003,"王五"); map.put(1003, "王五"); System.out.println(map); // 可以放对象 Map<String,Stduent> map1 = new HashMap(); Stduent s1 = new Stduent(1001,"小马"); Stduent s2 = new Stduent(1002,"小李"); Stduent s3 = new Stduent(1002,"小平"); map1.put("1",s1); map1.put("2",s2); map1.put("3",s3); System.out.println(map1); System.out.println("======map list"); //可以放List //1.1号同学 选 2门 2号同学选3门课 Map< String, List<Course> > map2 = new HashMap<>(); //准备的课程 Course c1 = new Course(1,"java"); Course c2 = new Course(2,"如何重新做人"); Course c3 = new Course(3,"母鸡的产后护理"); //1号同学 List<Course> list1 = new ArrayList<>(); list1.add(c1); list1.add(c2); //2号同学 List<Course> list2 = new ArrayList<>(); list2.add(c1); list2.add(c2); list2.add(c3); //把1号和2号添加到map map2.put("1",list1); map2.put("2",list2); System.out.println(map2); } }
package com.qfedu; import java.util.*; /** * @Author lcw * @Description Map * @Date 2021/7/2 */ public class Test5 { public static void main(String[] args) { // 1.key value 键值对 id=132 id:132 // 键 不可以重复 Map<String,String> map = new HashMap<String,String>(); //2.添加值 map.put("105","廉颇"); map.put("106","小乔"); map.put("107","赵云"); //3. 遍历 // 3. 获取key 的集合 Set<String> keys = map.keySet(); for (String key : keys) { // 4.获取单个值 get(key的值 ) String s = map.get(key); System.out.println(s); } // 3.2遍历方式二: Entry 条目 Set<Map.Entry<String, String>> entries = map.entrySet(); for (Map.Entry<String, String> entry : entries) { System.out.println("key="+entry.getKey()+ " value="+entry.getValue()); } // 收集所的value值 ,返回一个集合 Collection<String> values = map.values(); System.out.println("values="+values); //有几条数据 int size = map.size(); //是否包含某个 key boolean b = map.containsKey("106"); System.out.println("b==="+b); // --value值可能是个集合 Map<String, List> map1 = new HashMap<>(); List list = new ArrayList(); map1.put("140000",list); //value-- key -- value 主键--对象 Map<Integer,Hero> heroMap = new HashMap<>(); Hero hero = new Hero(); hero.setId(159); hero.setName("小乔"); heroMap.put(hero.getId(), hero); System.out.println(heroMap); } }
7.2.2 TreeMap
实现了SortedMap接口(Map的子接口),可以对key自动排序,Key需实现Comparable接口。
案例演示:使用TreeMap保存数据。
package com.qfedu; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * @Author lcw * @Description TreeMap * @Date 2021/7/2 */ public class Test6 { public static void main(String[] args) { TreeMap<Integer,Hero1> treeMap = new TreeMap<>(); Hero1 hero1 = new Hero1(); hero1.setId(114); hero1.setName("刘禅"); Hero1 hero2 = new Hero1(); hero1.setId(115); hero2.setName("阿斗"); treeMap.put(hero1.getId(),hero1); Set<Integer> keys = treeMap.keySet(); for (Integer key : keys) { System.out.println(treeMap.get(key)); } Set<Map.Entry<Integer, Hero1>> entries = treeMap.entrySet(); for (Map.Entry<Integer, Hero1> entry : entries) { Integer key = entry.getKey(); Hero1 value = entry.getValue(); } } }
7.2.3 其他实现类
Hashtable :
JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value。
Properties :
Hashtable的子类,要求key和value都是String。通常用于配置文件的读取。
迭代器:获取当前对象的迭代器
例如:Iterator <String> 名字=集合.Iterator();
方法:hasNext()//有没有下一个
next();//获取下一个元素
增强for:数组或者集合的名字.for