Java集合框架超详细笔记

Java集合框架超详细笔记


文章目录

1. 集合的引入_对象数组


能够存储对象的一个数组;

需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到数组中,并遍历5个学生信息;

1)首先得自定义一个学生类 Student(name姓名,age年龄)

2)定义一个数组(对象数组)---->学生数组

3)创建5个学生对象

4)将s1到s5存储到数组中

5)遍历学生对象,输出每一个学生的姓名和年龄;

//学生类
public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", 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;
	}
	
}
public static void main(String[] args) {
		//定义一个学生数组
		Student student[] = new Student[5];
		//创建学生对象
		Student s1 = new Student("卡卡1",23);
		Student s2 = new Student("卡卡2",20);
		Student s3 = new Student("卡卡3",21);
		Student s4 = new Student("卡卡4",24);
		Student s5 = new Student("卡卡5",26);

		//将学生对象插入数组
		student[0] = s1;
		student[1] = s2;
		student[2] = s3;
		student[3] = s4;
		student[4] = s5;
		
		//遍历学生数组
		for(int i = 0; i < student.length; i++){
			Student s = student[i] ;
			System.out.println(s.getName()+"---"+s.getAge());
		}
		
	}
  • 因为学生存在增删改查行为,数组虽然可以存储多个对象但是长度是固定的,不符合长度可变的要求因此引入集合的概念;

2. 集合的概念


概念:对象的容器,存储对象的对象可以代替数组;面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java提供了集合类;

特点:

  • 容器的工具类,定义了对多个对象进行操作的常用方法。

位置:java.util.*; 里面。

集合和数组的区别:

  1. 长度的区别

    数组:长度是固定的;

    集合:长度是可变的;

  2. 内容的区别

    数组:只能存储同一种数据类型 int[] arr = new int[5];

    集合:只能存储一种数据类型;

  3. 存储数据类型问题

    数组:既可以存储基本数据类型,又可以存储引用数据类型;

    集合:只能存储引用数据类型;

  • 数组:length属性
  • String:存在length()方法
  • 集合:size()方法

3. Collection接口


      Collection 层次结构中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的;

      JDK不提供此接口的任何直接实现:它提供更具体的子接口(如 Set 和 List)实现子实现类,接口不能实例化;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nb9rGNZ4-1592762980989)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200620102523851.png)]

3.1 Collection的基本功能

  • boolean add(Object e):添加任意类型的元素
  • boolean remove(Object o):删除指定的元素
  • void clear() : 暴力删除(删除集合中的所有元素)
  • boolean contains(Object o) :是否包含指定的元素,如果包含,返回true
  • boolean isEmpty():判断集合是否为空
  • int size():获取集合的元素数
public static void main(String[] args) {
		//提供子接口实现
		Collection c = new ArrayList();
		//添加任意类型的元素
		c.add("hello");
		c.add("java");
		c.add("123");
		
		//删除指定的元素
		System.out.println(c.remove("hello"));
		
		//暴力删除(删除集合中的所有元素)
		c.clear();
		
		//是否包含指定的元素,如果包含,返回true
		System.out.println("contains():" + c.contains("kaka"));//false
		System.out.println("contains():" + c.contains("123"));//true

		//判断是否为空
		System.out.println("isEmpty():" + c.isEmpty());//返回Boolean类型
		
		//获取集合的元素数
		System.out.println("size():" + c.size());//3
	}
}

3.2 Collection的高级功能

  • boolean addAll(Collection c):添加一个集合中的所有元素

  • boolean removeAll(Collection c):删除集合中所有元素(该元素一定是在另一集合中也包含的)------>删除一个集合中元素算删除

  • boolean containsAll(Collection c):一个集合中 包含指定 集合 中的所有元素(包含所有算包含)

  • boolean retainAll(Collection c):一个集合对另一个集合取交集

    如果一个集合A对一个集合B取交集,交集的元素保存在A集合中,B集合不变的

    返回值boolean表达的意思A集合中的元素,是否发生变化,如果没有发生变化,

    返回false;如果变化,返回true;

public static void main(String[] args) {
		//创建两个Collection集合
		Collection<String> c1 = new ArrayList<String>();
		Collection<String> c2 = new ArrayList<String>();
		
		//添加元素
		c1.add("kaka1") ;
		c1.add("kaka2") ;
		c1.add("kaka3") ;
		c1.add("kaka4") ;
		
		c2.add("kaka1") ;
		c2.add("kaka2") ;
		c2.add("kaka3") ;
		c2.add("kaka4") ;
		c2.add("kaka5") ;
		c2.add("kaka6") ;
		
		System.out.println("c1:"+c1);
		System.out.println("c2:"+c2);

		//添加一个集合中的所有元素
		System.out.println("addAll():" + c1.addAll(c2));
		
		//删除集合中所有元素(该元素一定是在另一集合中也包含的)
		System.out.println("removeAll():"+c1.removeAll(c2));
		
		//一个集合中包含指定集合中的所有元素(包含所有算包含)
		System.out.println("containsAll():"+c1.containsAll(c2));//false
		System.out.println("containsAll():"+c2.containsAll(c1));//true

		//一个集合对另一个集合取交集
		System.out.println("retainAll():"+c1.retainAll(c2));//没有发生变化false
		System.out.println("retainAll():"+c2.retainAll(c1));//发生变化true

		System.out.println("c1:"+c1);
		System.out.println("c2:"+c2);
	}

3.3 集合转对象数组遍历

  • Object[] toArray():将集合转换成对象数组

给集合中添加字符串数据并遍历;

public static void main(String[] args) {
		//创建一个集合对象
		Collection<String> c = new ArrayList<String>();
		
		//给集合中添加元素
		c.add("kaka");
		c.add("hello");
		c.add("java");
		
		//Object[] toArray();
		//里面存储的字符串数据----相当于:Object[] objs = new String()
		Object[] obj = c.toArray();
		//遍历数组
		for(int i = 0; i < obj.length; i++){
			String s = (String)obj[i];
			System.out.println(s + "---" + s.length());
		}
	}

3.3.1 Object[] toArray遍历案例_01

需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到集合中,并遍历5个学生信息

1)定义一个学生类

2)创建集合对象 Collection

3)创建5个学生

5)将5个学生添加到集合中

6)将集合转换成Object[] toArray

7)遍历数组

//Student类
public class Student {
	private String name;
	private int age;
    
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	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 "Student [name=" + name + ", age=" + age + "]";
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
}

public static void main(String[] args) {
		//创建集合对象
		Collection<Student> c = new ArrayList<Student>();
		
		//创建对象
		Student s1 = new Student("卡卡",23);
		Student s2 = new Student("张三",23);
		Student s3 = new Student("李四",23);
		Student s4 = new Student("王五",23);
		Student s5 = new Student("赵六",23);
		
		//集合中添加元素
		c.add(s1);
		c.add(s2);
		c.add(s3);
		c.add(s4);
		c.add(s5);
		
		//将集合转换为object[]数组
		Object[] obj = c.toArray();
		
		//遍历数组
		for(int i = 0; i < obj.length; i++){
			Student s = (Student)obj[i];
			System.out.println(s.getName() + "---" +s.getAge());
		}
		
	}

3.4 集合的专有遍历方式_迭代器

迭代器遍历:

  • Iterator iterator():获取集合的迭代器(集合专用遍历方式)

  • Iterator:迭代器(接口)

    Object next() :获取下一个元素------>是对 Object[] toArray()这个方法封装

    (是通过ArrayList集合实现的(内部类)next())

    boolean hasNext():判断功能,判断是否有下一个元素

迭代器的使用步骤:

  1. 创建集合对象

  2. 给集合对象中添加元素

  3. 获取迭代器

    3.1 判断当前迭代器是否有下一个可以遍历的元素

    3.2 在获取下一个元素

public static void main(String[] args) {
		//创建集合对象
		Collection<String> c = new ArrayList<String>();
		
		//给集合中添加字符串元素
		c.add("kaka");
		c.add("hello");
		c.add("java");
		
		//使用迭代器遍历
		Iterator<String> it = c.iterator();
		
		while(it.hasNext()){
			//向下转型
			String s = (String)(it.next());
			System.out.println(s + "---" + s.length());
		}
	}

3.4.1 迭代器遍历案例_02

需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到集合中,并遍历5个学生信息

1)定义一个学生类

2)创建集合对象 Collection

3)创建5个学生

5)将5个学生添加到集合中

6)创建迭代器

7)利用迭代器遍历集合

/*
 * 学生类
 */
public class Student {
	private String name;
	private int age;

	
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	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 "Student [name=" + name + ", age=" + age + "]";
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
}
public static void main(String[] args) {
		//创建集合对象
		Collection<Student> c = new ArrayList<Student>();
		
		//创建对象
		Student s1 = new Student("卡卡",23);
		Student s2 = new Student("张三",23);
		Student s3 = new Student("李四",23);
		Student s4 = new Student("王五",23);
		Student s5 = new Student("赵六",23);
		
		//集合中添加元素
		c.add(s1);
		c.add(s2);
		c.add(s3);
		c.add(s4);
		c.add(s5);
		
		//迭代器
		Iterator<Student> it = c.iterator();
		
		 //遍历
		while(it.hasNext()){
			Student s = (Student)(it.next());
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
  • 注:使用迭代器获取next()下一个元素的时候,一定看清楚集合存储的元素是什么类型,否则会出现ClassCaseException------>类型转换异常;

4. List接口与实现类


4.1 List接口概述

      有序的 collection,此接口的用户可以对列表中每个元素的插入位置进行精确地控制。 用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

      有序集合,改接口可精确控制每个元素的插入位置。通过整数索引访问元素,搜索列表中的元素。

特点:

  • 有序、有下标、元素可重复。

  • 继承了父接口提供的共性方法,同时定义了一些独有的与下标相关的操作方法。

4.1.1 存储字符串并遍历案例

public static void main(String[] args) {
		//创建一个List集合对象
		List<String> list = new ArrayList<String>();
		
		//添加元素
		list.add("kaka");
		list.add("hello");
		list.add("world");
		list.add("java");
		list.add("kaka");
		
		//使用Collection的迭代器
		Iterator<String> it = list.iterator();
		//遍历
		while(it.hasNext()){
			String s = (String)(it.next());
			System.out.println(s + "---" + s.length());
		}
	}

4.2 List的集合特有功能

  • void add(int index,Object element):在指定的位置处添加元素
  • Object remove(int index):删除指定索引处的元素
  • Object get(int index):获取功能: 获取指定索引处的元素
  • Object set(int index,E element):在指定位置处,修改元素内容
  • ListIterator listIterator(): list集合的专有遍历方式:列表迭代器
public static void main(String[] args) {
		//创建List集合对象
		List<String> list = new ArrayList<String>();
		
		//添加元素
		list.add("kaka");
		list.add("hello");
		list.add("world");
		list.add("java");
		
		//在指定的位置处添加元素
		list.add(2, "python");
		
		//删除指定索引处的元素
		System.out.println(list.remove(2));//python
		
		//获取指定索引处的元素
		System.out.println(list.get(0));//kaka
		
		//在指定位置处修改元素内容
		System.out.println(list.set(0, "卡卡"));//kaka
		System.out.println("list:" +list);//[卡卡, hello, world, java]
	}

4.2.1 get(int index)+size()相结合遍历案例_03

需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到集合中,并遍历5个学生信息

1)定义一个学生类

2)创建集合对象 List

3)创建5个学生

5)将5个学生添加到集合中

6)get(int index)+size()相结合遍历

//学生类
public class Student {
	private String name ;
	private int age ;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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 "Student [name=" + name + ", age=" + age + "]";
	}
}
		//创建一个List集合对象
		List<Student> list1 = new ArrayList<Student>();
		
		//创建5个学生对象
		Student s1 = new Student("卡卡",23);
		Student s2 = new Student("张三",23);
		Student s3 = new Student("李四",23);
		Student s4 = new Student("王五",23);
		Student s5 = new Student("赵六",23);
		
		//get(int index)+size()相结合 普通for循环
		for(int x = 0 ; x < list.size() ; x ++) {
			Student s  =(Student)(list1.get(x)) ;
			System.out.println(s.getName()+"---"+s.getAge());
		}
	}

4.3 列表迭代器_ ListIterator

ListIterator listIterator(): list集合的专有遍历方式:列表迭代器;

ListIterator:接口

  • 正向遍历

    boolean hasNext() :判断是否有下一个可以迭代的元素

    Object next() :获取下一个元素

  • 逆向遍历

    boolean hasPrevious() :判断是否有上一个可以迭代的元素

    Object previous() :获取上一个元素

public static void main(String[] args) {
		//创建一个List集合
		List<String> list = new ArrayList<String>();
		
		//添加字符串元素
		list.add("kaka");
		list.add("hello");
		list.add("java");
		
		//获取列表迭代器
		ListIterator<String> lit = list.listIterator();
		//遍历
		while(lit.hasNext()) {
			String s = (String)(lit.next()) ;
			System.out.println(s);
		}
		System.out.println("--------------------");
		//逆向遍历
		while(lit.hasPrevious()) {
			String s = (String)(lit.previous()) ;
			System.out.println(s);
		}
	}

4.3.1 使用迭代器遍历的问题

如果使用迭代器遍历元素,就不能使用集合添加元素;

java.util.ConcurrentModificationException:并发修改异常 ;

4.3.1.1 使用迭代器遍历,迭代器添加元素
public static void main(String[] args) {
		//创建一个List集合对象
		List<String> list = new ArrayList<String>();
		
		//集合存储三个元素
		list.add("hello") ;
		list.add("world") ;
		list.add("java") ;
		
		//由于Collection的Iterator迭代器没有添加功能的,所以列表迭代器
		ListIterator<String> lit = list.listIterator() ;
		while(lit.hasNext()) {
			String s  = (String)(lit.next()) ;
			//判断
			if("world".equals(s)) {
				//迭代器添加元素
				lit.add("javaee");
			}
		}
		System.out.println("list:"+list);
4.3.1.2 使用集合遍历,集合添加元素
public static void main(String[] args) {
		//创建一个List集合对象
		List<String> list = new ArrayList<String>();
		
		//集合存储三个元素
		list.add("hello") ;
		list.add("world") ;
		list.add("java") ;

		//普通for循环:get(int index) 和 size()方法先结合
		for(int i = 0 ;i < list.size() ; i ++) {
			//获取元素
			String s = (String)(list.get(i)) ;
			//判断
			if("world".equals(s)) {
				//使用集合添加
				list.add("javaee") ;
			}
		}
		System.out.println("list:"+list);
	}

4.4 集合的四种遍历方式案例

public static void main(String[] args) {
		//创建ArrayList集合对象
		ArrayList<String> array = new ArrayList<String>() ;
		
		//给集合中添加元素
		array.add("kaka") ;
		array.add("hello") ;
		array.add("world") ;
		array.add("world") ;
		array.add("java") ;
		array.add("java") ;
		
		//1:Object[] toArray遍历
		Object[] objs = array.toArray() ;
		for(int x = 0 ; x < objs.length ; x ++) {
			String s = (String)(objs[x]) ;
			System.out.println(s+"---"+s.length());
		}
		System.out.println("-----------------------");
		
		//2:Collection的迭代器
		Iterator<String> it = array.iterator() ;
		while(it.hasNext()) {
			String s = (String)(it.next()) ;
			System.out.println(s+"---"+s.length());
		}
		
		System.out.println("-----------------------");
		//3:使用List集合的列表迭代器
		ListIterator<String> lit = array.listIterator() ;
		while(lit.hasNext()) {
			String s = (String)(lit.next()) ;
			System.out.println(s+"---"+s.length());
		}
		System.out.println("-----------------------");
		
		//4:Object get(int index) 和int size()方法相集合
		for (int i = 0; i < array.size(); i++) {
			String s = (String)(array.get(i)) ;
			System.out.println(s+"---"+s.length());
		}
	}

4.5 List集合的三个子实现类的特点

  • ArrayList:

    底层数据结构:数组----->查询快,增删慢

    从线程角度考虑:此实现不是同步的---->线程不安全---->执行效率高!

  • LinkedList:

    底层数据结构:链接列表(链表)---->查询慢,增删快

    从线程角度考虑:此实现不是同步的----->线程不安全---->执行效率高!

  • Vector:

    底层数据库结构:可增长的数组实现---->查询快.增删慢
    线程方面: 线程安全—>同步----->执行效率低!

除多线程环境外,在需求中没有指定具体的集合---->都使用ArrayList ()

4.6 ArrayList集合

见4.4,4.5;

4.6.1 存储自定义对象并遍历

需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到集合中,并遍历5个学生信息

1)定义一个学生类

2)创建集合对象 ArrayList

3)创建5个学生

5)将5个学生添加到集合中

6)创建迭代器

7)利用迭代器遍历集合

//学生类
public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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 "Student [name=" + name + ", age=" + age + "]";
	}
}
public static void main(String[] args) {
		//创建ArrayList集合对象
		ArrayList<Student> array = new ArrayList<Student>();
		
		//创建5个学生对象
		Student s1 = new Student("卡卡",23);
		Student s2 = new Student("张三",23);
		Student s3 = new Student("李四",23);
		Student s4 = new Student("王五",23);
		Student s5 = new Student("赵六",23);
		
		//集合中添加元素
		array.add(s1);
		array.add(s2);
		array.add(s3);
		array.add(s4);
		array.add(s5);
		
		//迭代器
		Iterator<Student> it = array.iterator();
		
		//遍历
		while(it.hasNext()){
			Student s = (Student)(it.next());
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}

4.6.2 案例:获取10个1-20之间的随机数,要求不能重复,使用ArrayList集合

public static void main(String[] args) {
    ArrayLists();
}

private static void ArrayLists() {
		ArrayList<Integer> arr = new ArrayList<>();
		
		Random r = new Random();

		while(arr.size() != 10){
			int number = r.nextInt(20)+1 ;
			if(!arr.contains(number)){
				 arr.add(number) ;
			}

		}
		System.out.println("ArrayList版本:");
		//遍历
		Iterator<Integer> it = arr.iterator();
		while(it.hasNext()){
			Integer i = (Integer)(it.next());
			System.out.print(i + "\t");
		}
	}

4.7 Vector集合

见4.5

通过整数索引访问组件;

线程安全的类:StringBuffer 和 Vector

Vector类特有功能:

  • public void addElement(Object obj):给Vector集合中添加元素 ------->类似于add(Object obj)

  • public Object elementAt(int index):通过整数索引值获取指定元素内容---->类似于Object get(int index)

  • public Enumeration elements() :就是Vector集合的专有遍历方式:返回Enumeration接口(枚举元素)----->类似于:Iterator iterator()

    Enumeration接口:

    • boolean hasMoreElements():判断枚举中是否存在元素
    • Object nextElement():获取下一个枚举元素
public static void main(String[] args) {
		//创建Vector集合对象
		Vector<String> v = new Vector<String>();
		
		//给Vector集合中添加元素
		v.add("kaka");
		v.add("hello");
		v.add("world");
		v.add("java");
		
		//通过整数索引值获取指定元素内容 + size()遍历Vector集合
		for(int i = 0; i < v.size(); i++){
			String s = (String)(v.elementAt(i));
			System.out.println(s + "---" + s.length());
		}
		System.out.println("------------");
		
		//特有遍历
		Enumeration<String> em = v.elements();
		while(em.hasMoreElements()){
			String s = (String)(em.nextElement());
			System.out.println(s + "---" + s.length());
		}
	}

4.8 ListedList集合

见4.5

ListedList集合特有功能:

  • 添加

    public void addFirst(Object e):将指定元素始终在链表开头添加

    public void addLast(Object e):将指定的元素在链表的末尾添加

  • 获取

    public Object getFirst() :获取链表的第一个元素

    public Object getLast() :获取链表的最后一个元素

  • 删除

    public Object removeFirst():删除链表第一个元素

    public Object removeLast() :删除链表最后一个元素

public static void main(String[] args) {
		//创建一个LinkeList集合对象
		LinkedList<String> link = new LinkedList<String>() ;
		
		link.add("hello") ;
		link.add("world") ;
		link.add("java") ;
		
		//将指定元素始终在链表开头添加
		link.addFirst("javaee");
		link.addFirst("android");
		
		//将指定的元素在链表的末尾添加
		link.addLast("go");
		link.addLast("R");
		
		//获取链表的第一个元素,返回被获取的元素
		System.out.println("getFirst():"+link.getFirst());//android
		
		//获取链表的最后一个元素
		System.out.println("getLast():"+link.getLast());//R
		
		//删除链表第一个元素
		System.out.println("removeFirst():"+link.removeFirst());//android
		
		//删除链表最后一个元素
		System.out.println("removeLast():"+link.removeLast());//R
		
		System.out.println("link:"+link);//[javaee, hello, world, java, go]
	}

4.8.1 利用ListedList 集合模拟栈结构特点_01

栈的特点:先进后出;

利用ListedList 中的 public void addFirst(Object e)方法,将指定元素始终在链表开头添加,实现模拟栈的结构特点;

public static void main(String[] args) {
		//创建一个LinkedList集合
		LinkedList<String> link = new LinkedList<String>() ;
		
		//addFirst()添加
		link.addFirst("kaka");
		link.addFirst("hello");
		link.addFirst("java");
		
		//遍历
		//使用迭代器
		Iterator<String> it = link.iterator();
		while(it.hasNext()) {
			String s = (String)(it.next()) ;
			System.out.println(s);
		}
	}

4.8.2 利用ListedList 集合模拟栈结构特点_02

利用ListedList 中的 public void addFirst(Object e)方法,将指定元素始终在链表开头添加,在利用public Object removeFirst()方法,删除链表第一个元素;一加一删来实现模拟栈结构特点;

import java.util.LinkedList;

/**
 * 自定义的栈集合类
 * @author 卡卡
 *
 */
public class MyStack {
	private LinkedList link;
	
	//定义无参构造
	public MyStack(){
		link = new LinkedList();
	}
	/**
	 * 添加
	 */
	public void add(Object obj){
		link.addFirst(obj);
	}
	/**
	 * 获取
	 */
	public Object get(){
		return link.removeFirst();
	}
	
	/**
	 * 判断
	 */
	public boolean isEmpy(){
		return link.isEmpty();
	}
}
/*
 * 测试类
 */
public class MyStackTest {
	public static void main(String[] args) {
		//创建MyStack对象
		MyStack my = new MyStack();
		
		//添加元素
		my.add("kaka");
		my.add("hello");
		my.add("world");
		
		while(!my.isEmpy()){
			//获取元素
			System.out.println(my.get());
		}
	}
}

4.9 List 案例_01

需求:在ArrayList存储了一些重复元素,去重ArrayList重复的元素!(字符串元素)

创建一个新集合的思想

  1. 创建一个ArrayList集合对象 array
  2. 给集合中添加很多重复元素
  3. 创建一个新的集合newArray
  4. 遍历以前的集合
  5. 判断新集合如果不包含这个元素,就将这个元素添加到新集合中
  6. 遍历新集合
public static void main(String[] args) {
		//创建一个ArrayList集合
		ArrayList<String> arr = new ArrayList<>();
		
		//给集合中添加重复元素
		arr.add("kaka");
		arr.add("hello");
		arr.add("world");
		arr.add("java");
		arr.add("kaka");
		arr.add("hello");
		arr.add("kaka");
		arr.add("java");
		
		//创建一个新集合
		ArrayList<String> newArr = new ArrayList<>();
		
		//遍历以前的元素
		Iterator<String> it = arr.iterator();
		while(it.hasNext()){
			//获取元素
			String s = (String)(it.next());
			//判断新集合如果不包含这个元素,添加到新集合中;
			if(! newArr.contains(s)){
				newArr.add(s);
			}
		}
		//遍历新集合
		Iterator<String> itN = newArr.iterator();
		while(itN.hasNext()){
			String s = (String)(itN.next());
			System.out.println(s);
		}
	}

4.10 List案例_02

需求:在ArrayList存储了一些重复元素,去重ArrayList重复的元素!(字符串元素)

不创建新集合,利用选择排序的思想

  • 使用0索引对应的元素和后面索引的元素进行比较,如果后面的元素和前面元素一致,就将后面重复元素从集合删除掉----->remove(int index)
  1. 创建ArrayList集合对象
  2. 添加重复元素
  3. 利用选择排序的思想,删除重复的元素
  4. 遍历集合
public static void main(String[] args) {
		//创建一个ArrayList集合
		ArrayList<String> arr = new ArrayList<>();
		
		//给集合中添加重复元素
		arr.add("kaka");
		arr.add("hello");
		arr.add("world");
		arr.add("java");
		arr.add("kaka");
		arr.add("hello");
		arr.add("kaka");
		arr.add("java");
		
		
		 //利用选择排序的思想,将后面重复元素从集合删除掉
		for(int i = 0 ;i < arr.size()-1 ;i ++) {
			for(int j = i+1 ; j < arr.size(); j++) {
				//如果后面元素和前面的元素重复了,删除后面元素,里面索引--
				//通过角标获取集合元素内容get(int index)
		if(arr.get(i).equals(arr.get(j))) {
					//删除
					arr.remove(j) ;
					j -- ;
				}
			}
		}
		
		//遍历集合
		Iterator<String> it = arr.iterator() ;
		while(it.hasNext()) {
			String s = (String)(it.next()) ;
			System.out.println(s);
		}
	}

4.11 List案例_03

需求:使用ArrayList集合存储自定义对象Student并去重

1)定义一个学生类

2)创建集合对象 ArrayList

3)创建5个学生

5)将5个学生添加到集合中

6)创建迭代器

7)利用迭代器遍历集合

重点:重写equals方法

//学生类
public class Student {
	private String name ;
	private int age ;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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 "Student [name=" + name + ", age=" + age + "]";
	}

	@Override
	public boolean equals(Object obj) { //Student s ;
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())//获取字节码文件对象: this.getClass  
			return false;
		Student other = (Student) obj;
		if (age != other.age) //比较当前学生类中成员信息
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name)) //String name
			return false;
		return true;
	}
}

public static void main(String[] args) {
		//创建ArrayList集合对象
		ArrayList<Student> arr = new ArrayList<>();
		
		//创建学生对象
		//创建对象
		Student s1 = new Student("卡卡",23);
		Student s2 = new Student("张三",23);
		Student s3 = new Student("李四",23);
		Student s4 = new Student("卡卡",23);
		Student s5 = new Student("王五",23);
		Student s6 = new Student("赵六",23);

		//添加到集合中
		arr.add(s1);
		arr.add(s2);
		arr.add(s3);
		arr.add(s4);
		arr.add(s5);
		arr.add(s6);
		
		//创建一个新集合
		ArrayList<Student> newArr = new ArrayList<>();
		
		//遍历以前的集合
		Iterator it = arr.iterator();
		while(it.hasNext()){
			Student s = (Student)(it.next());
			if(!newArr.contains(s)){
				newArr.add(s);
			}
		}
		//遍历新的集合
		Iterator<Student> it2 = newArr.iterator();
		for(int i = 0; i < newArr.size();i++){
			Student s = (Student)(newArr.get(i));
			System.out.println(s.getName() + "---" +s.getAge());
		}
	}

5. Set集合与实现类


5.1 Set 概述

Set接口就是一个不包含重复元素的collection;全部继承自Collection中的方法;

特点:

       无序、无下标、元素不可以重复

Set集合和List集合的区别:

  • List集合:有序的集合,存储和取出是一致的,它允许元素重复
  • Set集合:无序的集合,存储和取出不一致(不能保证该顺序恒久不变),它元素唯一的
public static void main(String[] args) {
	//创建一个Set集合对象
    Set<String> set = new HashSet<String>();

    //添加元素
    set.add("hello");
    set.add("hello");
    set.add("java");
    set.add("java");
    set.add("world");
    set.add("world");

    //增强for遍历
    for(String s :set){
        System.out.println(s);//java	world	hello


    }
}
  • 元素不能重复

5.2 Set集合中的子实现类

Set中的子实类包括HashSet、LinkedHashSet、TreeSet

5.2.1 HashSet类概述

HashSet集合的add方法跟HashMap集合的put有关系,将所有需要存入HashSet的值,直接保存在HashMap中,底层依赖于hashCode()、equals()方法。需要在自定义的类中重写hashCode()和equals方法();

需求:使用HashSet集合存储自定义对象Student,保证元素唯一

//学生类
public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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 int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		//result = 31 * 29 + name的哈希值
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}

public static void main(String[] args) {
    //创建一个HashSet集合对象
    Set<Student> set = new HashSet<Student>();

    //创建学生对象
    Student s1 = new Student("卡卡",23);
    Student s2 = new Student("张三",26);
    Student s3 = new Student("卡卡",24);
    Student s4 = new Student("张三",26);
    Student s5 = new Student("卡卡",34);

    //添加集合中
    set.add(s1);
    set.add(s2);
    set.add(s3);
    set.add(s4);
    set.add(s5);

    //增强for遍历
    for(Student s : set){
    System.out.println(s.getName()+"---"+s.getAge());
    }
}

以上代码输出:

卡卡—23
卡卡—24
卡卡—34
张三—26

5.2.2 LinkedHashSet类概述

元素有序唯一,底层数据结构是链接列表和哈希表

  • 链接列表: 来保证元素有序(存储和取出一致的)
  • 哈希表: 来保证元素唯一性

节点形式单独存储数据,并可以指向下一个节点,通过顺序访问节点,可保留元素插入顺序;

public static void main(String[] args) {
    //创建LinkedHashSet集合对象
    LinkedHashSet<String> link = new LinkedHashSet<String>();

    //添加元素
    link.add("hello");
    link.add("hello");
    link.add("kaka");
    link.add("kaka");
    link.add("javaEE");
    link.add("javaEE");
    link.add("android");

    //遍历
    for(String s : link){
        System.out.println(s);
    }
}

以上代码输出:

hello
kaka
javaEE
android

6 TreeSet 类概述(重)


底层数据结构是红黑树一种自平衡的二叉树;

1). 实现了SortedSet接口,要求必须可以对元素排序,使用元素的自然顺序对元素进行排序。

2). 所有插入元素,必须实现Comparable接口,覆盖compareTo方法。

3). 根据compareTo方法返回0作为去重的依据

6.1 Red - Black - Tree 红黑树结构简述

红黑树一种自平衡的二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。

public static void main(String[] args) {
    //创建TreeSet集合对象
    TreeSet<Integer> ts = new TreeSet<Integer>();
    
	//add()添加
    ts.add(20) ; 
    ts.add(18) ;
    ts.add(23) ;
    ts.add(22) ;
    ts.add(17) ;
    ts.add(24) ;
    ts.add(19) ;
    ts.add(18) ;
    ts.add(24) ;

    //遍历集合
    for(Integer i : ts) {
        System.out.print(i+" ");//17 18 19 20 22 23 24 
    }
}

遍历原理:拿上面的数字20,18,23,22,17,24,19,18,24来说:

存储元素:

  1. 添加元素时,第一个元素20作为根节点---->root
  2. 后面添加的元素都需要和根节点进行比较
  3. 如果比根节点小,作为根节点的左孩子(根节点左边的子节点)
  4. 如果比根节点打,作为根节点的右孩子(根节点右边的子节点)
  5. 如果元素相等,不会进入到红黑树的结构中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PfUZvbcY-1592762980994)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200621231132497.png)]

遍历元素:

使用中序遍历(左根右)

  1. 首先访问根节点的左孩子,如果这个左孩子仍然有左孩子继续访问,一直到没有左孩子的节点,输出该节点17;
  2. 依据中序遍历次序,输出17的父节点18,;
  3. 在输出18的右孩子19;
  4. 以节点18为大的左孩子输出完毕,在输出整个二叉树的根节点20;
  5. 依据中序遍历次序左根右,找到根节点20的右孩子23,因为23有左孩子所以输出23的左孩子22;
  6. 输出22的根节点23;
  7. 在输出23的右孩子24;
  8. 最终得到序列17,18,19,20,22,23,24

6.2 TreeSet 集合案例_按照学生的年龄从小到大排序

TreeSet集合存储自定义对象,并且主要条件按照学生年龄的长度(从小到大比较)

  • 主要条件:年龄从小到大排序

  • 次要条件:

    长度如果一样,还需要比较姓名的内容

    需要比较人的年龄是否一样

/*
 * 如果要使用自然排序,针对自定义,该自定义类必须实现Comparable接口
 * 重写 compareTo(T s)方法对元素进行比较
 */
public class Student implements Comparable<Student>{
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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 "Student [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int compareTo(Student s) {
		// TODO Auto-generated method stub
		int num = this.age - s.age;
		int num2 = (num == 0?(this.name.compareTo(s.name)):num);
		return num2;
	}
	
}
public static void main(String[] args) {
    TreeSet<Student> ts = new TreeSet<Student>();

    Student s1 = new Student("kaka",23);
    Student s2 = new Student("kaka",21);
    Student s3 = new Student("kaaka",28);
    Student s4 = new Student("kkkkaka",26);
    Student s5 = new Student("ka11ka",24);
    Student s6 = new Student("kakaaa",23);
    Student s7 = new Student("kaka",23);

    //添加元素
    ts.add(s1);
    ts.add(s2);
    ts.add(s3);
    ts.add(s4);
    ts.add(s5);
    ts.add(s6);
    ts.add(s7);

    //遍历
    for(Student s : ts){
    System.out.println(s.getName()+"---"+s.getAge());
    }
}

以上代码输出:

kaka—21
kaka—23
kakaaa—23
ka11ka—24
kkkkaka—26
kaaka—28

6.3 TreeSet 集合案例_按照学生的

姓名长度从小到大排序

/*
 * 学生类
 */
public class Student implements Comparable<Student> {
	
	
	private String name ;
	private int age ;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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 "Student [name=" + name + ", age=" + age + "]";
	}
	
	//重写Comparable接口的方法
	@Override
	public int compareTo(Student s) {  
		
		//主要条件按照学生姓名的长度(从小到大)
		int num = this.name.length() - s.name.length() ;
		
		//1)次要条件:姓名的长度一样,姓名的内容不一定一样
		int num2 = num == 0 ? (this.name.compareTo(s.name)) : num;
		//2)次要条件:姓名的长度一样,内容一样,年龄不一定一样
		int num3 = num2 == 0 ? (this.age-s.age) : num2 ;
		return num3 ;
	}
}	
public static void main(String[] args) {
		
		//创建一个TreeSet集合 对象
		TreeSet<Student> ts = new TreeSet<Student>() ; //实现自然排序
		
		//创建学生对象
		Student s1 = new Student("kaka",23);
	    Student s2 = new Student("kaka",21);
	    Student s3 = new Student("kaaka",28);
	    Student s4 = new Student("kkkkaka",26);
	    Student s5 = new Student("ka11ka",24);
	    Student s6 = new Student("kakaaa",23);
	    Student s7 = new Student("kaka",23);
		
		ts.add(s1) ;
		ts.add(s2) ;
		ts.add(s3) ;
		ts.add(s4) ;
		ts.add(s5) ;
		ts.add(s6) ;
		ts.add(s7) ;
		
		//增强for
		for(Student s :ts) {
			System.out.println(s.getName()+"---"+s.getAge());
		}
	}

以上代码输出:

kaka—21
kaka—23
kaaka—28
ka11ka—24
kakaaa—23
kkkkaka—26

6.4 TreeSet集合两种比较器排序

构造方法:

  • TreeSet():创建TreeSet集合对象使用自然排序

  • TreeSet(Comparator comparatpr):比较器排序

    • 构造方法的形式参数是一个接口类型:

      1. 自定义类实现Comarator接口,重写compare(T o1 ,T o2)方法

      2. 接口的匿名内部类

        new 接口名(){

               重写接口中的方法;

        };

注:6.4.1和6.4.2学生类都是以下

/*
 * 学生类
 */
public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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 "Student [name=" + name + ", age=" + age + "]";
	}
}

6.4.1 自定义类实现Comparator接口

/*
 * Comparator接口
 */
public class MyComparator implements Comparator<Student>{
	public MyComparator() {
		
	}
	@Override
	public int compare(Student s1, Student s2) {
		//s1----->this
		//s2---->传进来被比较的对象
		//主要条件:按照学生年龄从小到大
		int num = s1.getAge() - s2.getAge() ;
		
		//次要条件:如果年龄一样,比较姓名的内容是否一样
		int num2  = num == 0 ? (s1.getName().compareTo(s2.getName())) : num ;
		return num2;
	}
}
public static void main(String[] args) {
    //创建一个TreeSet集合对象
    //TreeSet(Comparator comparatpr):比较器排序

    TreeSet<Student> ts = new TreeSet<Student>(new MyComparator()) ;

    //创建几个学生对象
    Student s1 = new Student("kaka",23);
    Student s2 = new Student("kaka",21);
    Student s3 = new Student("kaaka",28);
    Student s4 = new Student("kkkkaka",26);
    Student s5 = new Student("ka11ka",24);
    Student s6 = new Student("kakaaa",23);
    Student s7 = new Student("kaka",23);

    //添加元素
    ts.add(s1) ;
    ts.add(s2) ;
    ts.add(s3) ;
    ts.add(s4) ;
    ts.add(s5) ;
    ts.add(s6) ;
    ts.add(s7) ;

    //遍历
    for(Student s: ts) {
        System.out.println(s.getName()+"---"+s.getAge());
    }
}

以上代码输出:

kaka—21
kaka—23
kakaaa—23
ka11ka—24
kkkkaka—26
kaaka—28

6.4.2 直接接口的匿名内部类

public static void main(String[] args) {
		//直接接口的匿名内部类
		TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {

			@Override
			public int compare(Student s1, Student s2) {
			
				//s1----->this
				//s2---->传进来被比较的对象
				//主要条件:按照学生年龄从小到大
				int num = s1.getAge() - s2.getAge() ;
				
				//次要条件:如果年龄一样,比较姓名的内容是否一样
				int num2  = num == 0 ? (s1.getName().compareTo(s2.getName())) : num ;
				return num2;
			}	
		});

		//创建几个学生对象
		Student s1 = new Student("kaka",23);
	    Student s2 = new Student("kaka",21);
	    Student s3 = new Student("kaaka",28);
	    Student s4 = new Student("kkkkaka",26);
	    Student s5 = new Student("ka11ka",24);
	    Student s6 = new Student("kakaaa",23);
	    Student s7 = new Student("kaka",23);
		
		//添加元素
		ts.add(s1) ;
		ts.add(s2) ;
		ts.add(s3) ;
		ts.add(s4) ;
		ts.add(s5) ;
		ts.add(s6) ;
		ts.add(s7) ;
		
		//遍历
		for(Student s: ts) {
			System.out.println(s.getName()+"---"+s.getAge());
		}
		
	}
}

以上代码输出:

kaka—21
kaka—23
kakaaa—23
ka11ka—24
kkkkaka—26
kaaka—28

7. Map接口与实现类


7.1 Map接口的概述

Map集合数据结构<K,V> 键值对存储一对数据;

Map接口的特点:

  • 用于存储任意类型的键值对(Key-value)
  • 键:无序、无下标、不允许重复(唯一)
  • 值:无序、无下标、允许重复
  • 针对键有效,跟值无关

Map接口和Collection接口的不同:

  • Map是双列的,存储一堆键值对元素,特点针对键有效,键是唯一的可理解为(夫妻对),数据结构值针对键有效跟值无关;
  • Collection是单列的 ,只能存储一种引用数据类型,子体系Set是唯一的,理解为光棍,数据结构是针对元素有效;

7.2 Map集合的基本功能

  • V put(K key,V value) :添加一个键值对元素(后面的值会将前面的值覆盖,存储到集合,返回第一次存储的键对应的值)
  • V remove(Object key) :删除键,返回键对应的值
  • void clear() :暴力删除(删除全部键值对元素)
  • boolean containsKey(Object key):判断是否包含指定的键
  • boolean containsValue(Object value):判断是否包含指定的值
  • boolean isEmpty() :判断Map集合是否为空
  • int size() :获取集合的元素数
	public static void main(String[] args) {
		//创建Map集合对象
		Map<String,String> map = new HashMap<String,String>();
		
		//添加一个键值对元素  
		//后面的值会将前面的值覆盖,存储到集合,返回第一次存储的键对应的值
		//第一次添加返回null
		System.out.println(map.put("卡卡", "涛涛"));//null
		System.out.println(map.put("卡卡", "牛牛"));//涛涛
		System.out.println(map);//{卡卡=牛牛}
		
		//删除键,返回键对应的值
		System.out.println("remove():"+map.remove("杨过"));
		
		//暴力清除  
		map.clear();
		
		//判断是否包含指定的键
		System.out.println("containsKey():"+map.containsKey("卡卡"));//true
		System.out.println("containsKey():"+map.containsKey("唐唐"));//false
		
		//判断是否包含指定的值
		System.out.println("containsValue():"+map.containsValue("牛牛"));//true
		
		//判断Map集合是否为空
		System.out.println("isEmpty():"+map.isEmpty());//false
		
		//获取集合的元素数
		System.out.println(map.size());//1
		
		System.out.println(map);//{卡卡=牛牛}
	}

7.3 Map接口中的其他功能

  • V get(Object key):通过键获取值
  • Set < K> keySet() :获取所有的键的集合
  • Collection< V> values():获取所有的值的集合
  • Set<Map.Entry<K,V>> entrySet() :获取的是键值对对象(用于遍历详见7.4.2)
public static void main(String[] args) {
		//创建Map集合
		Map<String,String> map = new HashMap<String,String>() ; 
		
		//添加元素
		map.put("卡卡", "小卡") ;
		map.put("牛牛", "小牛") ;
		map.put("堂堂", "小堂") ;
		map.put("涛涛", "小涛") ;
		
		// 获取所有的键的集合
		Set<String> set = map.keySet() ;
		//增强for
		for(String key : set) {
			//通过键获取值
			String value = map.get(key) ;
			System.out.println(key+"="+value);
		}
		System.out.println("-----------------------");
		
		//获取所有的值的集合
		Collection<String> c = map.values() ;
		for(String value : c) {
			System.out.println(value);
		}
	}

上述代码输出:

卡卡=小卡
堂堂=小堂
涛涛=小涛
牛牛=小牛

小卡
小堂
小涛
小牛

7.4 Map集合的遍历

7.4.1 通过键找值

set< K > keySet() {}

  • 获取所有键的集合
  • 遍历键的集合,获取到每一个键
  • 根据键找值
public static void main(String[] args) {
		
		Map<String,String> map = new HashMap<String,String>(); 
		
		//添加元素
		map.put("卡卡", "小卡") ;
		map.put("牛牛", "小牛") ;
		map.put("堂堂", "小堂") ;
		map.put("涛涛", "小涛") ;
		
		
		//获取所有的键的集合
		Set<String> set = map.keySet() ;
		for(String key :set) {
			//通过键获取值 V get(Object key)
			String value = map.get(key) ;
			System.out.println(key+"="+value);
		}
	}

7.4.2 根据键值对对象找键和值

public Set<Map.Entry<K,V>> entrySet()

  • Map.Entry<K,V>接口中
    • K getKey():获取键
    • V getValue():获取值
  • 获取所有键值对对象的集合
  • 遍历键值对对象的集合,获取到每一个键值对对象
  • 根据键值对对象找键和值
public static void main(String[] args) {
		Map<String,String> map = new HashMap<String,String>() ; //HashMap:哈希表(元素唯一,无序!)
		
		//添加元素
		map.put("卡卡", "小卡") ;
		map.put("牛牛", "小牛") ;
		map.put("堂堂", "小堂") ;
		map.put("涛涛", "小涛") ;
		
		
		//通过map集合获取所有的键值对对象
		Set<Map.Entry<String, String>> entrySet = map.entrySet() ;
		for(Map.Entry<String, String> entry:entrySet ) {
			//通过entry所有的键值对对象
			String key = entry.getKey() ;
			String value = entry.getValue() ;
			System.out.println(key+"="+value);
		}
	}

7.5 HashMap 集合类

键是哈希表结构,可以保证键的唯一性;可以用null作为key或者value;

HashMap<K,V>:可以存储任意的引用类型数据;

  • HashMap< String ,String>
  • HashMap < String ,Integer>
  • HashMap < String ,Student>

7.5.1 相同类型

public static void main(String[] args) {
		//创建一个HashMap集合
		HashMap<String, String> map = new HashMap<String,String>() ;
		
		//添加元素
		map.put("卡卡", "小卡") ;
		map.put("牛牛", "小牛") ;
		map.put("堂堂", "小堂") ;
		map.put("涛涛", "小涛") ;
		
		//直接遍历
		Set<String> set = map.keySet() ;
		for(String key :set) {
			String value = map.get(key) ;
			System.out.println(key+"---"+value);
		}
}

7.5.2 不同类型

public static void main(String[] args) {
		//创建HashMap集合
		HashMap<String, Student> hm = new HashMap<String,Student>() ;
		
		hm.put("1001", new Student("卡卡",27)) ;
		hm.put("1002", new Student("牛牛",25)) ;
		hm.put("1003", new Student("堂堂",22)) ;
		hm.put("1004", new Student("涛涛",20)) ;
		hm.put("1005", new Student("丫丫",18)) ;
		
		//遍历集合
		Set<String> set = hm.keySet() ;
		for(String key :set ) {
			
			//通过键获取值
			Student s = hm.get(key) ;
			System.out.println(key+"---"+s.getName()+"---"+s.getAge());
		}
	}

7.5.3 自定义类型

如果HashMap键的类型是自定义的,必须重写hashCode()和equals方法()保证元素唯一;

  • String:学号
  • Key:Student类型:学生信息
/*
 * 自定义学生类
 */
public class Student {
	private String name ;
	private int age ;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", 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 int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}
public static void main(String[] args) {
		
		//创建一个HashMap集合
		HashMap<Student, String> hm = new HashMap<Student,String>() ;
		
		Student s1 = new Student("卡卡", 29) ;
		Student s2 = new Student("卡卡", 25) ;
		Student s3 = new Student("卡卡", 29) ;
		Student s4 = new Student("涛涛", 30) ;
		Student s5 = new Student("涛涛", 31) ;
		Student s6 = new Student("帆帆", 22) ;
		
		//添加元素
		hm.put(s1, "1001") ;
		hm.put(s2, "1002") ;
		hm.put(s3, "1003") ;
		hm.put(s4, "1004") ;
		hm.put(s5, "1005") ;
		hm.put(s6, "1006") ;
		
		Set<Student> set = hm.keySet() ;
		for(Student key :set) {
			String value = hm.get(key) ;
			System.out.println(key.getName()+"---"+key.getAge()+"---"+value);
		}
	}

7.6 Map案例

需求:键盘录入,获取字符串中每一个字母出现的次数

步骤:

  1. 创建键盘录入对象,录入字符串内容
  2. 创建Map集合,TreeMap<Character,Integer>
  3. 将字符串转换成字符数组
  4. 遍历字符数组,获取到每一个字符
  5. 利用Map集合对象通过键获取值 ,判断当前获取的值是否null
    • 如果为null,第一次添加,给值默认值1,map集合对象将键和值添加到集合
    • 如果不为null,说明键不是第一次添加,值自增,重写map集合键和值添加到集合中
  6. 创建字符串缓冲区对象StringBuilder
  7. 遍历TreeMap<Character,Integer>
  8. 使用字符串缓冲区对象将键和值拼接起来,转换成字符串
public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("输入内容:");
		String line = sc.next();
		//创建Map集合
		TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
		//字符串转化为数组
		char[] chs = line.toCharArray();
		//遍历数组
		for(char ch :chs){
			//通过键获取值
			Integer i = tm.get(ch);
			//判断是否为null
			if(i == null){
				tm.put(ch, 1);
				
			}else{
				i++;
				tm.put(ch, i);
			}
		}
		//创建字符串缓冲区对象
		StringBuilder sb = new StringBuilder();
		Set<Character> set = tm.keySet();//Map存到Set
		for(Character key :set){
			//获取值
			Integer value = tm.get(key);
			//拼接
			sb.append(key).append("(").append(value).append(")");
		}
		String result = sb.toString();
		System.out.println(result);
	}
}

7.7 集合的嵌套遍历 _01

ArrayList集合嵌套HashMap集合 ArrayList<HashMap<String,String>>

public static void main(String[] args) {
		//创建一个大集合
		ArrayList<HashMap<String,String>> array = new ArrayList<HashMap<String,String>>();
		
		//第一个子集合HashMap<String,String>
		HashMap<String,String> hm1 = new HashMap<String,String>();
		//添加元素
		hm1.put("卡卡", "小卡");
		hm1.put("牛牛", "小牛");
		
		//将第一个集合添加到大集合中
		array.add(hm1);
		
		//第二个子集合
		HashMap<String,String> hm2 = new HashMap<String,String>();
		//添加元素
		hm2.put("欧欧", "小欧");
		hm2.put("QQ", "小Q");
		array.add(hm2);
		
		//第三个子集合
		HashMap<String,String> hm3 = new HashMap<String,String>();
		//添加元素
		hm3.put("发发", "小发");
		hm3.put("安安", "小安");
		array.add(hm3);
		
		for(HashMap<String,String> map : array){
			//获取所有键的集合
			Set<String> set = map.keySet();
			for(String key : set){
				//键找值
				String value = map.get(key);
				System.out.println("\t" + key +"---" +value);
			}
		}
	}

7.8 集合的嵌套遍历 _02

HashMap集合嵌套ArrayList集合HashMap<String,ArrayList< String >>

  • 键:String
  • 值:HashMap<String,String>
public static void main(String[] args) {
		//创建一个大集合
		HashMap<String,ArrayList<String>> hm = new HashMap<String,ArrayList<String>>();
		
		//Key:String类型
		//value:ArrayList集合
		ArrayList<String> firstArray = new ArrayList<String>();
		firstArray.add("刘备");
		firstArray.add("曹操");
		//将子集合添加到大集合中
		hm.put("三国演义", firstArray);
		
		ArrayList<String> secArray = new ArrayList<String>();
		secArray.add("令狐冲");
		secArray.add("林平之");
		//将子集合添加到大集合中
		hm.put("笑傲江湖", secArray);
		
		ArrayList<String> thirArray = new ArrayList<String>();
		thirArray.add("宋江");
		thirArray.add("吴用");
		//将子集合添加到大集合中
		hm.put("水浒传", thirArray);
		
		//遍历
		//获取所有集合
		Set<String> set = hm.keySet();
		//遍历键
		for(String key : set){
			System.out.println(key);
			//通过键获取值
			ArrayList<String> list = hm.get(key);
			//遍历ArrayList
			for(String value : list){
				System.out.println("\t" + value);
			}
		}
	}

8. Collections工具类


集合工具类,针对集合操作的工具类,定义了除了存取以外的集合常用方法。

8.1 Collection 的成员方法

  • public static void sort(List list):针对集合进行默认的自然排序
  • public static < T > void sort(List< T > list, Comparator<? super T> c):针对List集合的比较器排序
  • public static int binarySearch(List<?> list,T key):集合中查询指定的元素出现的索引值(二分搜索法)
  • public static T max(Collection<?> coll):获取集合中的最大值
  • public static void reverse(List<?> list):直接集合的数据进行反转
  • public static void shuffle(List<?> list):针对集合中元素随机置换

注:折半查找(二分搜索法)---->数组中的元素必须有序的 ,数组的元素是无序的,就不能够直接使用二分搜索法

public static void main(String[] args) {
		//创建List集合对象
		List<Integer> list = new ArrayList<Integer>();
		
		//添加元素
		list.add(50);
		list.add(30);
		list.add(79);
		list.add(10);
		list.add(49);
		System.out.println(list);//[50, 30, 79, 10, 49]
		
		//针对集合进行默认的自然排序
		Collections.sort(list);
		System.out.println(list);//[10, 30, 49, 50, 79]
		
		//集合中查询指定的元素出现的索引值(二分搜索法)
		System.out.println("index:" + Collections.binarySearch(list, 30));//index:1
		
		//获取集合中的最大值
		System.out.println("max:" + Collections.max(list));//max:79
		
		//集合的数据进行反转
	   Collections.reverse(list);
	   System.out.println(list);//[79, 50, 49, 30, 10]
	   
	   //针对集合中元素随机置换
	   Collections.shuffle(list);
	   System.out.println(list);//[30, 50, 79, 10, 49]每次不定是随机生成的   
	}

8.2 针对List集合的比较器排序

public static < T > void sort(List< T > list, Comparator<? super T> c):针对List集合的比较器排序

需求:List集合中存储的是Student类型,按照学生的年龄从小到大排序,,排序的过程还能够保证集合元素唯一

/*
 * 学生类
 */
public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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 "Student [name=" + name + ", age=" + age + "]";
	}
	
}
public static void main(String[] args) {
		//创建一个List集合
		List<Student> list = new ArrayList<Student>();
		
		//创建学生对象
		Student s1 = new Student("kaka", 25) ;
		Student s2 = new Student("kaka", 25) ;
		Student s3 = new Student("zhangsan", 20) ;
		Student s4 = new Student("lisi", 20) ;
		Student s5 = new Student("wangwu", 22) ;
		Student s6 = new Student("zhaoliu", 30) ;
		
		//添加到list集合中
		list.add(s1);
		list.add(s2);
		list.add(s3);
		list.add(s4);
		list.add(s5);
		list.add(s6);
		
		//对当前学生排序,针对List集合的比较器排序
		//list集合是可以重复的
		Collections.sort(list, new Comparator<Student>() {
			@Override
			public int compare(Student s1, Student s2) {
				//年龄从小到大排:主要条件
				int num = s1.getAge() - s2.getAge() ;
				//年龄如果一样,不一定是同一个人,比较姓名的内容是否相同
				int num2 = num == 0 ? s1.getName().compareTo(s2.getName())  :num ;
				return num2 ;
			}
		});
		
		//遍历集合
		for(Student s :list){
			System.out.println(s.getName() + "---"+ s.getAge());
		}
	}

9. 模拟斗地主的洗牌和发牌_ 无序


需求:3个玩家 每一个玩家17张牌, 3张底牌

步骤:

  1. 有一个牌盒,创建一个牌盒 ArrayList< String >
  2. 装牌
    • 定义花色数组 String[] colors = {} ;
    • 定义点数数组 String[] numbers ={A,2,4…10,J,Q,K}
    • 遍历花色和点数数组
    • 花色和点数拼接,装到牌盒中
  3. 洗牌
    • Collections的blic static void shuffle(List<?> list):针对集合中元素随机置换
  4. 发牌
    • 三个人—>三个人都接收牌---- 每一个人都是是一个ArrayList< String > player1/player2/player3
    • 规律:几个人玩的话—>角标对人的个人求余判断情况
    • 判断:
      • 角标值如果大于等集合的元素-3为底牌
      • 如果当前角标 % 3 ==0为第一个玩家的牌
      • 如果当前角标 % 3 ==1为第二个玩家的牌
      • 如果当前角标 % 3 ==2为第三个玩家的牌
  5. 看牌
    将看牌封装一个功能,lookPoker
public class PokerTest {
	public static void main(String[] args) {
		//创建牌盒
		ArrayList<String> array = new ArrayList<String>();
		
		//装牌
		String colors[] = {"♠","♥","♣","♦"};
		String numbers [] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"} ;
		//遍历花色/点数
		for(String color :colors) {
			for(String number:numbers) {
				String poker = color.concat(number) ;
				//装进到牌盒中
				array.add(poker) ;
 			}
		}
		
		//添加大王,和小王
		array.add("小王") ;
		array.add("大王") ;
		//System.out.println(array);
		
		//洗牌 Collections shuffle(List<?> list):将牌随机置换
		Collections.shuffle(array);
		//System.out.println(array);
		
		//发牌
		//使用集合去接受
		ArrayList<String> player1 = new ArrayList<String>();
		ArrayList<String> player2 = new ArrayList<String>();
		ArrayList<String> player3 = new ArrayList<String>();
		ArrayList<String> dipai = new ArrayList<String>();

		for(int i = 0; i < array.size();i++){
			//底牌
			if(i >= array.size()-3){
				dipai.add(array.get(i));
			}else if(i %3 == 0){
				//第一个玩家的
				player1.add(array.get(i)) ;
			}else if(i % 3 == 1){
				//第二个玩家
				player2.add(array.get(i));
			}else if(i % 3 == 2){
//				第三个玩家
				player3.add(array.get(i));
			}
		}
		//看牌
		lookPoker("玩家一:" ,player1);
		lookPoker("玩家二:",player2);
		lookPoker("玩家三:",player3);
		lookPoker("底牌:",dipai);
	}
	//看牌方法
	public static void lookPoker(String name,ArrayList<String> array){
		System.out.print(name+ "的牌是:");
		//遍历集合
		for(String s : array){
			System.out.print(s + " ");
		}
		System.out.println();
	}
}

10. 模拟斗地主的洗牌和发牌_有序


需求:3个玩家 每一个玩家17张牌, 3张底牌

步骤:

  1. 创建一个牌盒,存储牌的编号以及对应的牌,HashMap< Integer,String>以及单独创建一个ArrayList< Integer >集合存储编号
  2. 装牌
    • 编号从0开始 index
    • 定义花色数组和点数数组
    • 将花色和点数进行拼接得到牌
    • 给HashMap集合添加编号对应的牌
    • 给ArrayList集合单独添加编号
    • 编号++
    • 装小王和大王(分别给HashMap<Intger,String> ArrayList< Integer >)
  3. 洗牌
    • 洗的是编号:ArrayList< Integer > ,使用Collections的public static void shuffle(List<?> list):针对集合中元素随机置换
  4. 发牌
    • 发的是编号,为了保证每个人手上的牌是排序的使用TreeSet< Integer >接收
    • 判断:
      • 角标值如果大于等集合的元素-3为底牌
      • 如果当前角标 % 3 ==0为第一个玩家的牌
      • 如果当前角标 % 3 ==1为第二个玩家的牌
      • 如果当前角标 % 3 ==2为第三个玩家的牌
  5. 看牌
    封装一个功能 ,lookPoker
public class PokerTest {
	public static void main(String[] args) {
		//创建一个牌盒
		HashMap<Integer,String> hm = new HashMap<Integer,String>();
		//存放编号
		ArrayList<Integer> array = new ArrayList<Integer>();
		
		//装牌
		int index = 0;
		String[] colors = {"♠","♥","♣","♦"};
		String [] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
		
		for(String number : numbers){
			for(String color :colors){
				String poker = color.concat(number);
				hm.put(index, poker);
				array.add(index);
				index++;
			}
		}
		hm.put(index, "小王");
		array.add(index);
		index++;
		hm.put(index, "大王");
		array.add(index);

		//洗牌
		Collections.shuffle(array);
		
		//发牌
		TreeSet<Integer> player1 = new TreeSet<Integer>();
		TreeSet<Integer> player2 = new TreeSet<Integer>();
		TreeSet<Integer> player3 = new TreeSet<Integer>();
		TreeSet<Integer> dipai = new TreeSet<Integer>();


		for(int i = 0; i<array.size(); i++){
			if(i >= array.size()-3){
				dipai.add(array.get(i));
			}else if(i % 3 == 0){
				player1.add(array.get(i));
			}else if(i % 3 == 1){
				player2.add(array.get(i));
			}else if(i % 3 == 2){
				player3.add(array.get(i));
			}
		}
		
		//看牌
		lookPoker("玩家一",player1,hm);
		lookPoker("玩家二",player2,hm);
		lookPoker("玩家三",player3,hm);
		lookPoker("底牌",dipai,hm);

		
		
	}
	public static void lookPoker(String name,TreeSet<Integer> array,HashMap<Integer,String> hm){
		System.out.print(name+"的牌是");
		for(Integer i : array){
			String value = hm.get(i);
			System.out.print(value +" ");
		}
		System.out.println();
	}
}
  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Willing卡卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值