1 集合框架家族族谱
1.1 顶级接口collection 实现这个接口的有 List接口(list是有序的,有索引可以储存重复的对象) 与 Set接口(存取顺序不一致,没有索引不能储存重复的对象)
2 集合与数组的区别
2.1 数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,太麻烦,java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少
2.2 数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值。集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象。
2.3 数组和集合什么时候用:如果元素个数是固定的推荐用数组,如果元素个数不是固定的推荐用集合
3 collection的常用方法
3.1 add()
add方法如果是List集合会一直返回true 因为List允许储存重复的元素 如果是Set集合当存储重复元素会返回false
import java.util.ArrayList; import java.util.Collection; public class Damo1 { public static void main(String[] args) { Collection c = new ArrayList(); boolean b1 = c.add("12"); boolean b2 = c.add(true); boolean b3 = c.add("abc"); boolean b4 = c.add("12"); System.out.println(b1); System.out.println(b2); System.out.println(b3); System.out.println(b4); } }
3.2 romve()删除指定元素
public class Damo2 { public static void main(String[] args) { Collection c = new ArrayList(); c.add("a"); c.add("b"); c.add("c"); c.add("d"); System.out.println("删除前的集合:" + c); c.remove("b");//删除指定元素 System.out.println("删除后的集合:" + c); } }
3.3 clear() 清空集合
import java.util.ArrayList; import java.util.Collection; public class Damo3 { public static void main(String[] args) { Collection c = new ArrayList(); c.add("a"); c.add("b"); c.add("c"); c.add("d"); System.out.println("清空前的集合:" + c); c.clear();//清空集合 System.out.println("清空后的集合:" + c); } }
3.4 contains() 判断集合中是否包含指定对象 返回布尔对象
import java.util.ArrayList; import java.util.Collection; public class Damo4 { public static void main(String[] args) { Collection c = new ArrayList(); c.add("a"); c.add("b"); c.add("c"); c.add("d"); System.out.println("集合:" + c); System.out.println(c.contains("c")); } }
3.5 isEmpty 判断集合是否为空 返回布尔类型
import java.util.ArrayList; import java.util.Collection; public class Damo5 { public static void main(String[] args) { Collection c = new ArrayList(); c.add("a"); c.add("b"); c.add("c"); c.add("d"); System.out.println("集合:" + c); System.out.println(c.isEmpty()); } }
3.6 size() 判断集合元素个数 返回int类型
import java.util.ArrayList; import java.util.Collection; public class Damo6 { public static void main(String[] args) { Collection c = new ArrayList(); c.add("a"); c.add("b"); c.add("c"); c.add("d"); System.out.println("集合:" + c); System.out.println(c.size()); } }
3.7 toArray() 集合转换数组
import java.util.ArrayList; import java.util.Collection; public class Damo7 { public static void main(String[] args) { Collection c = new ArrayList(); c.add("a"); c.add("b"); c.add("c"); c.add("d"); Object[] arr = c.toArray(); for (Object i : arr) { System.out.println(i); } } }
3.8 addAll() 将集合C1元素全部添加到C2中
import java.util.ArrayList; import java.util.Collection; public class Damo8 { public static void main(String[] args) { Collection c1 = new ArrayList(); c1.add("a"); c1.add("b"); c1.add("c"); c1.add("d"); Collection c2 = new ArrayList(); c2.add("a"); c2.add("b"); c2.add("c"); c2.add("d"); c2.addAll(c1); System.out.println(c2); } }
3.9 removeAll() 删除两个集合的交集
import java.util.ArrayList; import java.util.Collection; public class Damo9 { public static void main(String[] args) { Collection c1 = new ArrayList(); c1.add("a"); c1.add("b"); c1.add("c"); c1.add("d"); Collection c2 = new ArrayList(); c2.add("a"); c2.add("b"); c2.add("E"); c2.add("G"); c2.removeAll(c1); System.out.println(c2); } }
3.10 containsAll()判断c1是否包含c2 返回布尔类型
import java.util.ArrayList; import java.util.Collection; public class Damo10 { public static void main(String[] args) { Collection c1 = new ArrayList(); c1.add("a"); c1.add("b"); c1.add("c"); c1.add("d"); Collection c2 = new ArrayList(); c2.add("a"); c2.add("b"); boolean b1 = c1.containsAll(c2); System.out.println(b1); System.out.println(c2); } }
3.11 iterator() 迭代集合(遍历集合)
import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class Damo11 { public static void main(String[] args) { Collection c1 = new ArrayList(); c1.add("a"); c1.add("b"); c1.add("c"); c1.add("d"); //对元素进行迭代(遍历) Iterator it = c1.iterator(); //获取迭代器 while (it.hasNext()) { //如果迭代器不为空 System.out.println(it.next());//指针指向下一个元素 } } }
4 List接口常用方法
4.1 add() 指定位置插入元素(索引位置可以小于等于size 并且不能等于零 否则会抛异常)
import java.util.ArrayList; import java.util.List; public class Damo1 { public static void main(String[] args) { List list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); // add() 指定位置插入元素(索引位置可以小于等于size 并且不能等于零 否则会抛异常) list.add(2,"D"); System.out.println(list); } }
4.2 remove() 删除指定位置的元素 返回该元素的值
import java.util.ArrayList; import java.util.List; public class Damo2 { public static void main(String[] args) { List list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); // remove() 删除指定位置的元素 返回该元素的类型 Object obj = list.remove(2); System.out.println(obj); System.out.println(list); } }
4.3 get() 根据索引获取元素 (可利用改变其下标的方式 遍历集合)
public class Damo3 { public static void main(String[] args) { List list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); // get() 根据索引获取元素 (可利用改变其下标的方式 遍历集合) Object obj1 = list.get(2); System.out.println(obj1); } }
4.4 set() 修改指定位置的值
public class Damo4 { public static void main(String[] args) { List list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); System.out.println(list); list.set(0,"A"); // 修改指定位置的值 System.out.println(list); } }
小练习 (需求 判断集合中是否包含“Hello” 元素包含则添加“World”元素
注意点1 使用迭代器遍历集合 Iterator迭代器 没有add方法 需使用List的add方法 而List的add方法使用会产生并发修改异常(迭代器中记录了集合的元素 此时修改集合元素 会抛出ConcurrentModificationException异常 )
2 避开并发修改异常 可用 ListIterator类自带的add方法添加元素 代码如下
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; public class Test1 { public static void main(String[] args) { List list = new ArrayList(); list.add("a"); //添加进去的字符串是Object类型的 list.add("Hello"); list.add("b"); System.out.println(list); /* Iterator lt = list.iterator(); //获取迭代器 while (lt.hasNext()) { //判断集合中是否有元素 String str = (String) lt.next(); //集合元素的Object 需要向下转形 if (str.equals("Hello")) { //如果等于Hello 则添加World //Iterator 没有add方法 使用List的add方法 会产生并发修改异常(迭代器中记录了集合的元素 此时修改集合元素 会抛出ConcurrentModificationException异常 ) list.add("Wotld"); } }*/ //避开并发修改异常 可用 ListIterator类自带的add方法添加元素 ListIterator iterator = list.listIterator(); while (iterator.hasNext()) { //判断集合中是否有元素 String str = (String) iterator.next(); //集合元素的Object 需要向下转形 if (str.equals("Hello")) { //如果等于Hello 则添加World //ListIterator类自带的add方法添加元素 iterator.add("Wotld"); } } System.out.println(list); } }
5 Vector ( jdk1.0出现 jdk1.2并入集合实现List 现在用得很少 了解即可)
import java.util.Enumeration; import java.util.Vector; public class Vector_Test { public static void main(String[] args) { Vector vector = new Vector(); //添加元素 vector.addElement("a"); vector.addElement("b"); vector.addElement("c"); //遍历元素 Enumeration en = vector.elements(); while (en.hasMoreElements()) { System.out.println(en.nextElement()); } } }
6 数组与链表数据结构(数组 查询快,修改也快 增加删除慢,链表 查询慢,修改慢 增加删除快)
7 List的三个子类的特点
7.1 ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
7.2 Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构)
7.3 LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
Vector和ArrayList的区别
Vector是线程安全的,效率低
ArrayList是线程不安全的,效率高
共同点:都是数组实现的
ArrayList和LinkedList的区别
ArrayList底层是数组结果,查询和修改快
LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
共同点:都是线程不安全的
List有三个实现类我们到底使用谁呢?
查询多用ArrayList
增删多用LinkedList
如果都多ArrayList
8 ArrayList 集合
8.1 ArrayList集合小练习 (需求 去除集合中重复的字符串)
import java.util.ArrayList; import java.util.Iterator; public class Test1 { //去除集合中重复的元素 public static void main(String[] args) { // 1 建立原始集合 ArrayList arrayList = new ArrayList(); arrayList.add(1); arrayList.add(2); arrayList.add(3); arrayList.add(1); System.out.println(arrayList); // 2 调用方法获取去除重复元素后的集合 ArrayList newList = getSingle(arrayList); System.out.println(newList); } //传入原始集合 返回去除重复元素的新集合 static静态属性可在main方法直接调用 public static ArrayList getSingle(ArrayList list) { ArrayList newList = new ArrayList();// 1 创建新集合 Iterator iterator = list.iterator();// 2 获取传入集合的迭代器 while (iterator.hasNext()) { // 3 如果集合不为空 Object obj = iterator.next(); // 4 获取集合下一个元素 if (!newList.contains(obj)) { // 5 判断该集合是否包含此元素 newList.add(obj); // 6 不包含则加入新集合 } } return newList; //7 返回一个新的集合 } }
9 LinkedList的常用方法
import java.util.LinkedList; public class Damo1 { public static void main(String[] args) { LinkedList linkedList = new LinkedList(); // 1 添加元素到第一个位置 linkedList.addFirst(1); linkedList.addFirst(2); linkedList.addFirst(3); System.out.println(linkedList); // 2 添加元素到最后一个位置 linkedList.addLast(4); System.out.println(linkedList); // 3 获取第一个元素 System.out.println(linkedList.getFirst()); // 4 获取最后一个元素 System.out.println(linkedList.getLast()); // 5 删除第一个元素 linkedList.removeFirst(); System.out.println(linkedList); // 6 删除最后一个元素 linkedList.removeLast(); System.out.println(linkedList); // 7 获取指定元素 (linkedList的数据结构决定了其查找元素的方式:索引小于size除于2 从头部开始查找,索引大于size除于2 则从尾部开始查找) System.out.println(linkedList.get(0)); } }
10 栈与队列数据结构
栈
( 先进后出 脑补一个桶 数据是放在桶里的一个一个东西 先放进去的对象被压在下面 故先进后出)
队列
( 先进先出 脑补一条管道 管道两个口 一个对象从A出口放进去 可以从B出口出来 故先进先出)
10.1 栈结构小练习 (需求 LinkedList模拟栈结构 代码如下。。。 如需实现队列结构 同理)
import java.util.LinkedList; //封装LinkedList的方法模拟栈结构 public class Stack { private LinkedList list = new LinkedList(); //模拟进栈 public void in(Object obj) { list.addLast(obj); } //模拟出栈 public Object out() { return list.removeLast(); } //模拟栈结构是否为空 public boolean isEmpty() { return list.isEmpty(); } public static void main(String[] args) { Stack s = new Stack(); s.in("a"); s.in("b"); s.in("c"); while (s.isEmpty()) { System.out.println(s.out()); } } }
11 泛型
泛型的由来:通过Object转型问题引入,早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。
泛型好处 :提高安全性(将运行期的错误转换到编译期) , 省去强转的麻烦
泛型基本使用:<>中放的必须是引用数据类型
泛型使用注意事项:前后的泛型必须一致,或者后面的泛型可以省略不写(1.7的新特性菱形泛型)
11.1泛型高级之通配符 (了解即可)
泛型通配符<?>: 任意类型,如果没有明确,那么就是Object以及任意的Java类了
List< ? > list = new ArrayList<Integer>();
? extends E:向下限定,E及其子类
可以将子类对象添加到集合中
? super E: 向上限定,E及其父类
重写比较器 传入父类类型 继承的子类在调用比较器时会自动调用父类的比较器
12 HashSet (方法调用与ArrayList
相同,存储元素不可重复,存储顺序不确定)
13 LinkedHashSet(底层是链表实现的,是Set集合中唯一一个保证怎么存就怎么取的集合对象,是HashSet的子类,所以元素唯一的)
小练习 (需求: 获取十个随机数 ,随机数不能重复。把最终的随机数输出到控制台)
import java.util.HashSet; import java.util.Random; public class Damo1 { //需求 获取十个随机数 ,随机数不能重复。把最终的随机数输出到控制台 public static void main(String[] args) { // 1 要有Random类创建的随机数对象 Random random = new Random(); // 2 需要存储10个不能重复的随机数,所以我们用HashSet集合 HashSet<Integer> hashSet = new HashSet<Integer>(); // 3 如果HashSet的size是小于10就可以不断的存储 大于10停止存储 while (hashSet.size() < 10) { // 4 通过Random类的nextInt(n) 获取0到n之间的随机数不包括n,并将这些随机数存储到HashSet集合中 hashSet.add(random.nextInt(20)+1); } // 5 遍历HashSet for (int i : hashSet) { System.out.print(i+" "); } } }
小练习 (需求:使用Scanner从键盘读取一行输入,去掉其中重复字符,打印不同的那些字符)
import java.util.HashSet; import java.util.Scanner; public class Damo2 { //使用Scanner从键盘读取一行输入,去掉其中重复字符,打印不同的那些字符 public static void main(String[] args) { // 1 创建Scanner对象 Scanner scanner = new Scanner(System.in); System.out.println("请输入字符,回车提交"); // 2 创建HashSet对象 HashSet<Character> hashSet = new HashSet<>(); // 3 将字符串转换为字符数组,获取每一个字符存储在HashSet集合中,自动去除重复 String line = scanner.nextLine(); char[] arr = line.toCharArray(); for (char c : arr) { hashSet.add(c); } //4 打印集合中的内容 for(char c:hashSet){ System.out.print(c+" "); } } }
小练习 (需求:将集合中重复的元素去掉)
import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; public class Damo3 { //将集合中重复的元素去掉 public static void main(String[] args) { // 1 创建List集合存储若干个重复的元素 ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("aa"); arrayList.add("aa"); arrayList.add("bb"); arrayList.add("bb"); arrayList.add("bb"); arrayList.add("c"); // 2 单独定义方法去除重复 getSingle(arrayList); // 3 打印List集合去除重复后存储的元素 System.out.println(arrayList); } //去除重复的方法 public static void getSingle(List<String> list) { // 1 创建一个LinkedHashSet集合 LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(); // 2 将List集合中的元素添加到LinkedHashSe集合中 linkedHashSet.addAll(list); // 3 将List集合中的元素清除 list.clear(); // 4 将LinkedHashSet集合中的元素添加回list list.addAll(linkedHashSet); } }
14 TreeSet
(可用来对元素进行排序,可保证元素的唯一性 底层是二叉树 小的存储左边(负数),大的存储右边(正数),相等则不存(0))
使用方式
1 自然顺序(Comparable)
TreeSet类的add方法会把存入的对象提升为Comparable类型
调用对象的compareTo()方法和集合中的对象比较
compareTo方法()返回的结果进行存储
2 比较器顺序(Comparator)
创建TreeSet的时候可以制定一个Comparator
如果传入了Comparator的子类对象,那么就会按照compare()方法进行排序
add()方法内部会自动调用Comparator接口中的compare()排序
调用的对象是compare方法的第一个参数,集合中的对象是compare方法中的第二个参数
两种方法的对比
(没有的话会报ClassCastException)
TreeSet如果传入Comparator,就优先按照Comparator进行排序
14.1 重写排序方法compare方法(返回值 0 集合中只有一个元素 , 返回值 1 怎么存则怎么取 , 返回值-1 集合倒序存储)
14.2 compare方法小练习 (需求 将字符串按照长度排序)
import java.util.Comparator; import java.util.TreeSet; public class Damo4 { // 需求 将字符串按照长度排序 (默认排序方式 按照字符字典顺序排序) public static void main(String[] args) { // 因需要重写compare()方法 所以换成自定义类CompareByLen() TreeSet<String> ts = new TreeSet<>(new CompareByLen()); ts.add("aaaaa"); ts.add("ccccccc"); ts.add("a"); ts.add("ddd"); System.out.println(ts); } } //新建一个类实现Comparator<String>接口 此接口有compare(String s1, String s2)方法 ,equals()方法 //需要重写compare()方法,默认继承Object所以不用重写equals() class CompareByLen implements Comparator<String> { @Override //重写方法 按照字符串长度进行比较 public int compare(String s1, String s2) { int num = s1.length() - s2.length(); //长度为主要条件 return num == 0 ? s1.compareTo(s2) : num; //如果长度相同 按照字典顺序进行排序 } }
小练习 (需求 在一个集合中存放n个无序并且重复的字符串,定义一个方法 让其变得有序 并且不能去除重复)
import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.TreeSet; public class Damo5 { //需求 在一个集合中存放了n个无序并且重复的字符串,定义一个方法 让其变得有序 并且不能去除重复 public static void main(String[] args) { // 1 定义一个list集合,并存放重复的元素 ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("aaaaa"); arrayList.add("bbbbb"); arrayList.add("aaaaa"); arrayList.add("dd"); arrayList.add("cccc"); System.out.println("排序前:" + arrayList); // 2 调用自定义的方法 排序集合并保留重复 sort(arrayList); // 3 打印排序后的集合 System.out.println("排序后:"+arrayList); } //自定义排序方法 public static void sort(List arrayList) { // 1 创建TreeSet集合对象,因为String自己有比较功能,但是重复的元素不会被保留,所以我们需要比较器 //new TreeSet的时候传入一个实现了Comparator接口的比较器 因重新建立一个类太繁琐 所以我们用匿名内部类并重写compare()方法 TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() { @Override public int compare(String s1, String s2) { int num = s1.compareTo(s2); return num == 0 ? 1 : num; } }); // 2 将List 集合内的元素 添加到 treeSet集合(此时TreeSet集会自动调用比较器内重写的 compare()方法 所以可以排序并保留重复元素) treeSet.addAll(arrayList); // 3 将arrayList集合内的元素清空 arrayList.clear(); // 4 将经由treeSet排序号的元素填充回arrayList集合 arrayList.addAll(treeSet); } }
小练习(需求 从键盘接收一个字符串,对接收的字符串进行排序)
import java.util.Comparator; import java.util.Scanner; import java.util.TreeSet; public class Damo6 { //从键盘接收一个字符串,对接收的字符串进行排序 public static void main(String[] args) { // 1 从键盘录入字符串,Scanner Scanner scanner = new Scanner(System.in); System.out.println("请输入字符串"); // 2 将字符串转换为字符数组 String line = scanner.nextLine(); char[] arr = line.toCharArray(); //3 定义TreeSet集合传入比较器对字符排序并且保留重复(传入一个实现了Comparator接口的匿名内部类) TreeSet<Character> treeSet = new TreeSet<>(new Comparator<Character>() { @Override public int compare(Character c1, Character c2) { int num = c1 -c2; //自动拆箱 return num == 0 ? 1 : num; } }); // 4 遍历字符数组,将每一个字符存储在TreeSet集合中 for (char c1 : arr) { treeSet.add(c1); //自动装箱 } //打印排序后的字符 for (char c1 : treeSet) { System.out.print(c1); } } }
小练习( 需求 启动程序 可以从键盘接收多个整数,直到输入quit时结束输入,把所有整数倒序排序打印)
import java.util.Comparator; import java.util.Scanner; import java.util.TreeSet; public class Damo7 { // 启动程序 可以从键盘接收多个整数,直到输入quit时结束输入,把所有整数倒序排序打印 public static void main(String[] args) { // 1 创建 Scanner对象,键盘录入 Scanner scanner = new Scanner(System.in); // 2 创建TreeSet对象 传入比较器 TreeSet<Integer> treeSet = new TreeSet<>(new Comparator<Integer>() { @Override public int compare(Integer i1, Integer i2) { int num = i2 - i1; return num == 0 ? 1 : num; } }); // 3 无限循环 接收字符串 遇到quit 退出 while (true){ String line = scanner.nextLine(); if (line.equals("quit")){ break; } // 4 不是quit则将其转换为整数 并添加在集合中 Integer i = Integer.parseInt(line); treeSet.add(i); } // 5 打印经过排序后的集合 System.out.println(treeSet); } }
小练习( 需求 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台)
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
// 需求 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
public class Damo8 {
public static void main(String[] args) {
// 键盘 录入需要Scanner,创建键盘录入对象
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学生成绩格式:姓名,语文成绩,数学成绩,英语成绩");
//创建TreeSet集合对象,在TreeSet的构造函数中传入比较器按照总分比较
TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num = s2.getSum() - s1.getSum();
return num == 0 ? 1 : num;
}
});
//录入五个学生
while (treeSet.size() < 5) {
//键盘获取信息 并切割成字符串数组
String line = scanner.nextLine();
String[] arr = line.split(",");
//将字符串转换成数字
int chinese = Integer.parseInt(arr[1]);
int math = Integer.parseInt(arr[2]);
int english = Integer.parseInt(arr[3]);
//将这些信息封装成Student对象 并放入treeSet集合
treeSet.add(new Student(arr[0], chinese, math, english));
}
//打印排序后的学生信息
System.out.println("排序后的信息");
for (Student student : treeSet) {
System.out.println(student);
}
}
}
/**
* 定义学生类
* 成员变量:姓名,语文成绩,数学成绩,英语成绩,总成绩
* 成员方法:空参,有参构造方法,有参构造方法的参数分别是姓名,语文成绩,数学成绩,英语成绩
* toString方法在遍历集合中的Student对象打印对象引用时会显示属性值
*/
class Student {
private String name;
private int chinese;
private int math;
private int english;
private int sum;
public int getSum() {
return sum;
}
public Student() {
}
public Student(String name, int chinese, int math, int english) {
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
this.sum = chinese + math + english;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", chinese=" + chinese +
", math=" + math +
", english=" + english +
", sum=" + sum +
'}';
}
}
15 Map接口
A:Map接口概述
查看API可以知道:
将键映射到值的对象
一个映射不能包含重复的键
每个键最多只能映射到一个值
B:Map接口和Collection接口的不同
Map是双列的,Collection是单列的
Map的键唯一,Collection的子体系Set是唯一的
Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针对元素有效
HashSet底层add()方法依赖HashMap的put()方法
15.1 Map集合的功能概述
a:添加功能
V put(K key,V value):添加元素。
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
import java.util.HashMap; import java.util.Map; public class Damo1 { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); /* 添加功能 V put(K key,V value):添加元素。 如果键是第一次存储,就直接存储元素,返回null 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值*/ Integer i1 = map.put("小白", 11); Integer i2 =map.put("小白", 18); System.out.println(i1); System.out.println(i2); System.out.println(map); } }
b:删除功能
void clear():移除所有的键值对元素
V remove(Object key):根据键删除键值对元素,并把值返回
import java.util.HashMap; import java.util.Map; public class Damo2 { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); Integer i1 = map.put("小黑", 11); Integer i2 =map.put("小白", 18); Integer i3 =map.put("小红", 16); System.out.println(map); Integer i4 = map.remove("小黑"); //根据键删除元素 返回键 System.out.println(map); System.out.println(i4); map.clear();//清空元素 System.out.println(map); } }
c:判断功能
boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
import java.util.HashMap; import java.util.Map; public class Damo3 { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("小黑", 11); map.put("小白", 18); map.put("小红", 16); System.out.println(map); System.out.println(map.containsKey("小黑"));//判断是否包含传入的键 System.out.println(map.containsValue(18));//判断是否包含传入的值 System.out.println(map.isEmpty());//判断集合是否为空 } }
d:获取功能
Set<Map.Entry<K,V>> entrySet():
V get(Object key):根据键获取值
Set<K> keySet():获取集合中所有键的集合
Collection<V> values():获取集合中所有值的集合
import java.util.Collection; import java.util.HashMap; import java.util.Map; public class Damo4 { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("小黑", 11); map.put("小白", 18); map.put("小红", 16); System.out.println(map); //获取集合中所有的值 Collection<Integer> c = map.values(); System.out.println(c); } }
e:长度功能
int size():返回集合中的键值对的个数
System.out.println(map.size());
15.2 遍历Map(键找值)
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class Damo5 { //迭代Map集合 (map集合没有iterator方法) public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("小黑", 11); map.put("小白", 18); map.put("小红", 16); System.out.println(map); //方式一 使用迭代器 //获取所有的键 Set<String> keySet = map.keySet(); Iterator<String> it = keySet.iterator();//获取迭代器 while (it.hasNext()) { //判断集合中是否有元素 String key = it.next(); //获取每一个键 Integer value = map.get(key);//通过键获取值 System.out.println(key + "=" + value); } System.out.println("---------"); //方式二 使用增强for循环 for (String key : map.keySet()) { //map.keySet()是所有键的集合 System.out.println(key + "=" + map.get(key)); } } }
15.3 遍历Map(键值对 对象找键和值)
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class Damo6 { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("小白", 11); map.put("小黑", 15); map.put("小红", 19); //Map.Entry说明Entry是Map的内部接口,将键和值封装成了Entry对象,并存储在Set集合中 Set<Map.Entry<String, Integer>> entries = map.entrySet(); //用迭代器遍历 获取每一个对象 Iterator<Map.Entry<String, Integer>> it = entries.iterator(); while (it.hasNext()) { //获取每一个Entry对象 Map.Entry<String, Integer> en = it.next(); String key = en.getKey(); Integer value = en.getValue(); System.out.println(key + "=" + value); } System.out.println("==========="); //用增强for循环遍历 for (Map.Entry<String,Integer> en :map.entrySet()) { System.out.println(en.getKey()+"="+en.getValue()); } } }
16 LinkedHashMap的特点 底层是链表实现的可以保证怎么存就怎么取
17 HashMap和Hashtable的区别
Hashtable是JDK1.0版本出现的,是线程安全的,效率低,HashMap是JDK1.2版本出现的,是线程不安全的,效率高
Hashtable不可以存储null键和null值,HashMap可以存储null键和null值
18 Collections类概述 ( 针对集合操作 的工具类 )
Collections成员方法
public static <T> void sort(List<T> list) 排序
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("d"); list.add("b"); list.add("c"); System.out.println(list); Collections.sort(list);//排序数组 System.out.println(list); }
public static <T> int binarySearch(List<?> list,T key) 二叉树查找元素位置 不存在则返回应插入元素 的负值-1
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("d"); list.add("b"); list.add("c"); System.out.println(Collections.binarySearch(list,"e")); }
public static <T> T max(Collection<?> coll) 查找最大值
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); System.out.println(list); System.out.println(Collections.max(list)); //查找最大值 }
public static void reverse(List<?> list) 集合反转
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); System.out.println(list); Collections.reverse(list);//集合反转 System.out.println(list); }
public static void shuffle(List<?> list) 集合随机打乱
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); System.out.println(list); Collections.shuffle(list); //随机置换集合内的元素 System.out.println(list); }
小练习 (统计字符串中每个字符出现的次数)
// 统计字符串中每个字符出现的次数 public class Damo9 { public static void main(String[] args) { // 1 定义字符串 String str = "aaaaccccvvvveee"; // 2 将字符串转换成字符数组 char[] array = str.toCharArray(); // 3 定义双列集合,存储字符串中字符以及字符出现的次数 HashMap<Character, Integer> map = new HashMap<>(); // 4 遍历字符数组获取每一个字符,并将字符存储到双列集合中 for (char c : array) { // 5 判断集合中是否包含元素 不包含则直接存键与值1 包含则值+1覆盖保存 map.put(c, !map.containsKey(c) ? 1 : map.get(c) + 1); } //打印统计结果 System.out.println(map); } }
小练习(模拟斗地主洗牌和发牌)
import java.util.ArrayList; import java.util.Collections; //需求 模拟斗地主的洗牌与发牌 public class Damo1 { public static void main(String[] args) { // 1 生成一副扑克牌 String[] num = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}; //数值 String[] color = {"红桃", "黑桃", "方块", "梅花"}; //花色 ArrayList<String> poker = new ArrayList<>(); //存储牌的集合 // 1.1 拼接牌 for (String s1 : num) { for (String s2 : color) { poker.add(s2.concat(s1));//concat() 方法连接两个字符串 } } poker.add("小王"); poker.add("大王"); // 2 洗牌 Collections.shuffle(poker); // 3 发牌 //3.1 生成三个人 与底牌集合 ArrayList<String> a1 = new ArrayList<>(); ArrayList<String> a2 = new ArrayList<>(); ArrayList<String> a3 = new ArrayList<>(); ArrayList<String> dipai = new ArrayList<>(); // 3.2 分配牌 for (int i = 0; i < poker.size(); i++) { if (i >= poker.size() - 3) { dipai.add(poker.get(i)); //将三张底牌存储在底牌集合中 } else if (i % 3 == 0) { a1.add(poker.get(i)); //取余为3 将牌给a1 } else if (i % 3 == 1) { a2.add(poker.get(i));//取余为1 将牌给a2 } else { a3.add(poker.get(i));//剩的牌 将牌给a3 } } // 4 查看分配后的牌 System.out.println(a1); System.out.println(a2); System.out.println(a3); System.out.println(dipai); } }
小练习(模拟斗地主洗牌和发牌 优化 对每个人的牌进行排序)
import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.TreeSet; //需求 模拟斗地主的洗牌与发牌 //优化 对每个人的牌进行排序 public class Damo2 { public static void main(String[] args) { // 1 生成一副扑克牌 String[] num = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"}; //数值 String[] color = {"红桃", "黑桃", "方块", "梅花"}; //花色 HashMap<Integer, String> hashMap = new HashMap<>(); //存储索引和扑克牌 ArrayList<Integer> list = new ArrayList<>();//存储索引 方便洗牌 int index = 0; // 1.1 拼接扑克牌 并将索引添加到hashMap中 for (String s1 : num) { for (String s2 : color) { hashMap.put(index, s2.concat(s1)); list.add(index); index++; } } // 将大小王添加到双列集合中 hashMap.put(index, "小王"); list.add(index); index++; hashMap.put(index, "大王"); list.add(index); // 2 洗牌 Collections.shuffle(list); // 3 发牌 // 3.1 创建TreeSet集合 自动排序 TreeSet<Integer> a1 = new TreeSet<>(); TreeSet<Integer> a2 = new TreeSet<>(); TreeSet<Integer> a3 = new TreeSet<>(); TreeSet<Integer> dipai = new TreeSet<>(); // 3.2 分配牌 for (int i = 0; i < list.size(); i++) { if (i >= list.size() - 3) { //将三张底牌存储在底牌集合中 dipai.add(list.get(i)); } else if (i % 3 == 0) { a1.add(list.get(i)); //取余为3 将牌给a1 } else if (i % 3 == 1) { a2.add(list.get(i));//取余为1 将牌给a2 } else { a3.add(list.get(i));//剩的牌 将牌给a3 } } // 4 看牌 lookPack(hashMap, a1, "a1"); lookPack(hashMap, a2, "a2"); lookPack(hashMap, a3, "a3"); lookPack(hashMap, dipai, "底牌"); } //自定义看牌方法 参数列表 HashMap ,TreeSet ,String name public static void lookPack(HashMap<Integer, String> hm, TreeSet<Integer> ts, String name) { System.out.print(name + "的牌是:["); for (Integer i : ts) { // i 是双列集合中的每一个键 System.out.print(hm.get(i) + ","); } System.out.print("]\n"); } }
总结:
/**
* Collection
* List(存取有序,有索引,可以重复)
* ArrayList
* 底层是数组实现的,线程不安全,查找和修改快,增和删比较慢
* LinkedList
* 底层是链表实现的,线程不安全,增和删比较快,查找和修改比较慢
* Vector
* 底层是数组实现的,线程安全的,无论增删改查都慢
* 如果查找和修改多,用ArrayList
* 如果增和删多,用LinkedList
* 如果都多,用ArrayList
* Set(存取无序,无索引,不可以重复)
* HashSet
* 底层是哈希算法实现
* LinkedHashSet
* 底层是链表实现,但是也是可以保证元素唯一,和HashSet原理一样
* TreeSet
* 底层是二叉树算法实现
* 一般在开发的时候不需要对存储的元素排序,所以在开发的时候大多用HashSet,HashSet的效率比较高
* TreeSet在面试的时候比较多,问你有几种排序方式,和几种排序方式的区别
* Map
* HashMap
* 底层是哈希算法,针对键
* LinkedHashMap
* 底层是链表,针对键
* TreeMap
* 底层是二叉树算法,针对键
* 开发中用HashMap比较多
*/