生非贵之所能存,身非爱之所能厚;生亦非贱之所能夭,身亦非轻之所能薄。
--列子
Java中的容器类类库的用途是“保存对象”,并将其划分为两个不同的概念:
Collection:
一个独立元素的序列,这些元素都服从一条或多条规则。List必须按照插入的顺序保存元素,而Set中不能有相同的元素。Queue按照排队的规则来确定对象产生的顺序(通常与它们被插入的顺序相同)。
Map:
一组成对的“键值对”对象,允许你使用键来进行查找值。ArrayList允许你使用数字来查找值,因此在某种意义上讲,它将数字和对象进行了关联。映射表允许我们使用另一对象来查找某个对象,它也被称为“关联数组”,因为它将某些对象与另一些对象关联在一起;或者被称为”字典“,因为你可以使用键对象来查找对值对象,就像在字典中使用单词来定义一样。
图解:
一、Collection接口
Collection :集合层次结构中的根界面。集合表示一组被称为其元素的对象。一些集合允许重复元素,而其他集合不允许。
通过观察api发现,Collection一个接口,我们无法直接对其创建对象,要想使用Collection接口中的方法,应该寻找一个它具体实现的子类
利用这个子类对象,来使用Collection中的方法。
通过api介绍我们又能够知道Collection是单元素集合的顶层接口,它相关的集合有些可以元素重复,有些不可以。
Collection又向下分了两种类型的集合:List(元素可以发生重复的)和Set(元素唯一)
Collection(接口)
-List(接口)
ArrayList(具体实现子类)
-Set(接口)
我们找到了Collection中其中一个实现子类:ArrayList,我们借助创建该类的对象,来学习并使用Collection接口中的方法
我们使用ArrayList的无参构造方法来实现创建
Collection成员方法:
boolean add(E e)
boolean remove(Object o)
void clear()
boolean contains(Object o)
boolean isEmpty()
int size()
package day12;
/*
Collection:合层次结构中的根界面 。 集合表示一组被称为其元素的对象。 一些集合允许重复元素,而其他集合不允许。 】、
有些被命令和其他无序。 JDK不提供此接口的任何直接实现:它提供了更具体的子接口的实现,如Set和List
通过观察api发现,Collection是一个接口,我们无法直接对其创建对象,要想使用Collection接口中的方法,应该找一个它具体的实现子类
利用这个实现子类对象,来使用Collection中的方法。
通过api介绍我们又能够知道Collection是单元素集合的顶层接口,它相关的集合有些可以元素重复,有些不可以。
Collection又向下分了两种类型的集合:List(元素可以发生重复)和Set(元素唯一)
Collection(接口)
- List(接口)
ArrayList(具体实现子类)
- Set(接口)
我们找到了Collection中其中一个实现子类:ArrayList,我们借助创建该类的对象,来学习并使用Collection接口中的方法
我们可以使用ArrayList的无参构造方法来创建
Collection成员方法:
boolean add(E e)
boolean remove(Object o)
void clear()
boolean contains(Object o)
boolean isEmpty()
int size()
*/
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo1 {
public static void main(String[] args) {
Collection c1 = new ArrayList();
System.out.println("c1:"+c1);//重写的toString()方法来自AbstractCollection类中
System.out.println("============================");
//boolean add(Object e)向集合中添加元素
c1.add("hello");
c1.add(true);
c1.add(11.23);
c1.add(100);
c1.add('c');
c1.add(10000L);
System.out.println("c1: "+c1);
//boolean remove(Object o)从集合中删除某个元素
// c1.remove(100);//若删除的元素有重复的存在,只会删除最左边的第一个相同元素
// System.out.println("c1: "+c1);
//void clear()清空集合中的所有的元素
// c1.clear();
// System.out.println("c1: "+c1);
//boolean contains(Object o)判断集合中是否包含某个元素
System.out.println(c1.contains("hello"));
//boolean isEmpty()判断集合中是否有元素存在着
System.out.println(c1.isEmpty());
//int size() 获取集合中的元素个数
System.out.println(c1.size());
}
}
Collection中的成员方法:
boolean addAll(Collection c)
boolean removeAll(Collection c)
boolean containsAll(Collection c)
boolean retainAll(Collection c)
package day12;
/*
Collection中的成员方法:
boolean addAll(Collection c)
boolean removeAll(Collection c)
boolean containsAll(Collection c)
boolean retainAll(Collection c)
今后我们在开发中,一个集合只能存储一种数据类型的元素。
*/
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo2 {
public static void main(String[] args) {
Collection c1 = new ArrayList();
c1.add("hello");
c1.add("world");
c1.add("java");
c1.add("hadoop");
c1.add("hello");
Collection c2 = new ArrayList();
c2.add("hello");
c2.add("hadoop");
c2.add("nihao");
Collection c3 = new ArrayList();
c3.add("hello");
c3.add("hadoop");
System.out.println("c1: "+c1);
System.out.println("c2: "+c2);
System.out.println("c3: "+c3);
// System.out.println("============================");
//boolean addAll(Collection c)将直接添加另一个集合中所有单元素
// c1.addAll(c2);
// System.out.println("c1: "+c1);
// System.out.println("c2: "+c2);
//boolean removeAll(Collection c)从一个集合中移除另一个集合中所有的元素
// c1.removeAll(c2);
// System.out.println("c1: "+c1);
// System.out.println("c2: "+c2);
//boolean containsAll(Collection c)判断集合A中是否包含集合B所有元素
// System.out.println(c1.containsAll(c2));
// System.out.println(c1.containsAll(c3));
System.out.println("============================");
//boolean retainAll(Collection c)A集合和B集合做交集,重复的部分覆盖到A集合中,B集合不变
c1.retainAll(c2);
System.out.println("c1: "+c1);
System.out.println("c2: "+c2);
}
}
二、Inerator接口
Collection集合如何遍历
学习集合的4个步骤:
1、如何创建集合对象?
2、如何创建元素对象?
3、如何将元素对象添加到集合中?
4、如何遍历集合?
package day12;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo3 {
public static void main(String[] args) {
//创建一个集合对象
Collection c1 = new ArrayList();
//创建元素、添加元素
c1.add("hello");
c1.add("java");
c1.add("world");
c1.add("hello");
c1.add("hadoop");
//遍历集合
//方式1:Object[] toArray() 把集合转成数组,可以实现集合的遍历
Object[] arr1 = c1.toArray();
for (int i = 0; i < arr1.length; i++) {
Object o = arr1[i];//Object o = "hello"
String s = (String)o;
System.out.println(s + "," + s.length());
}
//方式2:Iterator iterator()迭代器遍历,Collection集合的专用遍历方式
//调用Collection接口中的iterator()方法获取集合对应的迭代器对象
//迭代器对象中存储了集合中每一个元素,Iterator类中有方法可以给我们使用获取元素对象
Iterator iterator = c1.iterator();//Iterator iterator = new Itr()
//通过观察源码发现,Itr类中只有next方法有返回值是Object类型的,该方法就是获取元素的方法
// Object o = iterator.next();//Object o = "hello"
// System.out.println(o);
// Object o1 = iterator.next();
// System.out.println(o1);
// Object o2 = iterator.next();
// System.out.println(o2);
// Object o3 = iterator.next();
// System.out.println(o3);
// Object o4 = iterator.next();
// System.out.println(o4);
// Object o5 = iterator.next();
// System.out.println(o5);
//我们应该在next方法调用之前,先看一看迭代器中下一个位置上是否有元素,若有元素,才能进行调用
//Iterator接口中提供了一个方法hasNext(),帮助我们判断下一个位置上是否有元素
while(iterator.hasNext()){
Object o = iterator.next();
System.out.println(o);
}
System.out.println("==============================");
while(iterator.hasNext()){
Object o = iterator.next();
System.out.println(o);
}//第二次发现没有放回值,是因为迭代器的底层逻辑问题。迭代器遍历只能使用一次
}
}
Iterator接口成员方法:
boolean hasNext()
E next()
package cday12;
/*
存储自定义对象并遍历
Student(name,age)
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo4 {
public static void main(String[] args) {
//1、创建Collection集合对象
Collection c1 = new ArrayList();
//2、创建元素对象
Student s1 = new Student("小花", 3);
Student s2 = new Student("小白", 5);
Student s3 = new Student("小黑", 6);
Student s4 = new Student("小黄", 2);
//3、将元素对象添加到集合中去
c1.add(s1);
c1.add(s2);
c1.add(s3);
c1.add(s4);
//4、遍历集合
//方式1:转数组再遍历
Object[] array = c1.toArray();
for (int i = 0; i < array.length; i++) {
Object o = array[i];//Object o = new Student("小花",3)
Student s = (Student)o;
System.out.println("姓名:" + s.getName() + ", 年龄:" + s.getAge());
}
System.out.println("-------------------------------");
//方式2:迭代器遍历
Iterator iterator = c1.iterator();
while(iterator.hasNext()){
Object o = iterator.next();
Student s = (Student) o;
System.out.println("姓名:" + s.getName() + ", 年龄:" + s.getAge());
}
}
}
三、List接口
需求:
使用List集合存储字符串元素,使用迭代器遍历,遍历的时候,如果遇到"java",就向集合中添加一个元素"shujia"
package day13;
/*
需求:
使用List集合存储字符串元素,使用迭代器遍历,遍历的时候,如果遇到"java",就向集合中添加一个元素"shujia"
我们按照需求编写代码,在遍历迭代器的时候,当遇到"java",我们是使用集合中add方法进行添加元素的,运行的时候就报错了
ConcurrentModificationException 并发修改异常,迭代器遍历的时候,无法使用集合的方法对集合本身做改动。
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ListDemo1 {
public static void main(String[] args) {
List list1 = new ArrayList();
list1.add("hello");
list1.add("java");
list1.add("hadoop");
list1.add("redis");
System.out.println("list1: " + list1);
// Iterator iterator = list1.iterator();
// while(iterator.hasNext()){
// Object o = iterator.next();
// String s = (String) o;
// if("java".equals(s)){
// list1.add("shujia");
// }
// }
//因为继承自父亲的迭代器中没有添加元素的方法,所有我们需要使用List中特有的迭代器进行遍历及添加
//通过观察源码发现,List中特有的迭代器中的add方法,不仅可以对迭代器中的元素进行添加,底层也针对原集合进行添加元素
//将原集合以及迭代器的版本号也设置成一样的了,所以将来再检查版本号的时候,原集合和迭代器的版本号是一样的
//这样就不会产生并发修改异常了
ListIterator listIterator = list1.listIterator();
while(listIterator.hasNext()){
Object o = listIterator.next();
String s = (String) o;
if("java".equals(s)){
listIterator.add("hello world");
}
}
System.out.println(list1);
Object[] array = list1.toArray();
for (int i = 0; i < array.length; i++) {
String s = (String) array[i];
if ("java".equals(s)){
list1.add("hello world");
}
}
System.out.println("list1: "+list1);
}
}
package day13;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo2 {
public static void main(String[] args) {
List list1 = new ArrayList();
Iterator iterator = list1.iterator();
list1.add("hello");
list1.add("java");
list1.add("hadoop");
list1.add("redis");
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("list1: "+list1);
}
}
四、ArrayList类(List接口)
ArrayList:底层数据结构是数组,查询快、增删慢,线程不安全的,效率高
/*
Collection:
- List(有序【指的是存储和取出的顺序是一致的】且可以发生重复,且有索引的概念)
- ArrayList: 底层数据结构是数组,查询快,增删慢,线程不安全的,效率高。
- Vector
- LinkedList
- Set(元素唯一且无序)
*/
package day13;
import java.util.ArrayList;
import java.util.Iterator;
/*
Collection:
- List(有序【指的是存储和取出的顺序是一致的】且可以发生重复,且有索引的概念)
- ArrayList: 底层数据结构是数组,查询快,增删慢,线程不安全的,效率高。
- Vector
- LinkedList
- Set(元素唯一且无序)
*/
public class ArrayListDemo1 {
public static void main(String[] args) {
//存储字符串并遍历
ArrayList list1 = new ArrayList();
list1.add("hello");
list1.add("world");
list1.add("java");
list1.add("apple");
list1.add("hello");
Iterator iterator = list1.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
例题:
(1)去除集合中字符串的重复值(字符串内容相同)
package day13;
import java.util.ArrayList;
public class ArrayListTest1 {
public static void main(String[] args) {
ArrayList list1 = new ArrayList();
list1.add("java");
list1.add("hadoop");
list1.add("hive");
list1.add("java");
list1.add("hello");
list1.add("hadoop");
System.out.println("list1: " + list1);
System.out.println("=======================");
ArrayList list2 = new ArrayList();
for (int i = 0; i < list1.size(); i++) {
String s = (String)list1.get(i);
if (!list2.contains(s)){
list2.add(s);
}
}
System.out.println("list2: "+list2);
}
}
(2)去除集合中自定义对象的重复值(对象的成员变量值都相同)
自定义:student类
package day13;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
测试类:ArrayListTest类
package day13;/
import java.util.ArrayList;
public class ArrayListTest2 {
public static void main(String[] args) {
ArrayList list1 = new ArrayList();
Student s1 = new Student("小黑", 18);
Student s2 = new Student("小白", 17);
Student s3 = new Student("小花", 18);
Student s4 = new Student("小红", 19);
Student s5 = new Student("小黑", 18);
list1.add(s1);
list1.add(s2);
list1.add(s3);
list1.add(s4);
list1.add(s5);
System.out.println("list1: " + list1);
System.out.println("=======================");
ArrayList list2 = new ArrayList();
for (int i = 0; i < list1.size(); i++) {
Student s = (Student) list1.get(i);
if (!list2.contains(s)){
list2.add(s);
}
}
System.out.println("list2: "+list2);
}
}
五、Vector类(List接口)
Vetcor:底层数据结构式数组,查询快,增删慢,线程安全的,效率低;
Collection:
- List(有序【指的是存储和取出的顺序是一致的】且可以发生重复,且有索引的概念)
- ArrayList: 底层数据结构是数组,查询快,增删慢,线程不安全的,效率高。
- Vector:底层数据结构是数组,查询快,增删慢,线程安全的,效率低
【即便Vector是线程安全的,我们今后也不用,我们会将不安全的ArrayList变成安全的】
- LinkedList:
- Set(元素唯一且无序)
Vector类中的特有功能:
public void addElement(E obj)
public E elementAt(int index)
public Enumeration elements()
package com.shujia.day13;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
/*
Collection:
- List(有序【指的是存储和取出的顺序是一致的】且可以发生重复,且有索引的概念)
- ArrayList: 底层数据结构是数组,查询快,增删慢,线程不安全的,效率高。
- Vector:底层数据结构是数组,查询快,增删慢,线程安全的,效率低
【即便Vector是线程安全的,我们今后也不用,我们会将不安全的ArrayList变成安全的】
- LinkedList:
- Set(元素唯一且无序)
Vector类中的特有功能:
public void addElement(E obj)
public E elementAt(int index)
public Enumeration elements()
*/
public class VectorDemo1 {
public static void main(String[] args) {
Vector vector = new Vector();
vector.add("hello");
vector.add("world");
vector.add("java");
vector.add("hadoop");
vector.add("hello");
vector.addElement("flink"); // 从效果上来看和调用add方法一样,都是在集合的末尾处添加元素,将来就使用add来替代它
Iterator iterator = vector.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("==============================");
//public E elementAt(int index) 根据索引获取元素
System.out.println(vector.elementAt(2)); // 从效果上来看和调用get方法一样,都是根据索引获取元素,将来就使用get来替代它
System.out.println(vector.get(2));
System.out.println("==============================");
//public Enumeration elements() 获取一个存储所有集合元素的容器,类似于迭代器
// 从效果上来看和使用迭代器一样,都是先判断下一个位置是否有元素,然后再获取,将来就使用迭代器来替代它
Enumeration elements = vector.elements();
while (elements.hasMoreElements()){
Object o = elements.nextElement();
System.out.println(o);
}
}
}
六、LinkedList类(List接口)
LinkedList:底层数据结构是双链表,增删快,查询慢,线程不安全的,效率高。
Collection:
- List(有序【指的是存储和取出的顺序是一致的】且可以发生重复,且有索引的概念)
- ArrayList: 底层数据结构是数组,查询快,增删慢,线程不安全的,效率高。
- Vector:底层数据结构是数组,查询快,增删慢,线程安全的,效率低
【即便Vector是线程安全的,我们今后也不用,我们会将不安全的ArrayList变成安全的】
- LinkedList:底层数据结构是双链表,增删快,查询慢,线程不安全的,效率高。
- Set(元素唯一且无序)
LinkedList类特有功能:
public void addFirst(E e)及addLast(E e)
public E getFirst()及getLast()
public E removeFirst()及public E removeLast()
package day13;
import java.util.Iterator;
import java.util.LinkedList;
public class LinkedListDemo1 {
public static void main(String[] args) {
LinkedList list1 = new LinkedList();
list1.add("hello");
list1.add("world");
list1.add("java");
list1.add("hadoop");
list1.add("hello");
System.out.println(list1);
System.out.println("====================");
list1.addFirst("小花");
list1.addLast("小胡");//add
System.out.println(list1);
System.out.println("===========================");
System.out.println(list1.getFirst());
System.out.println(list1.getLast());
System.out.println("================================");
System.out.println(list1.removeFirst());
System.out.println(list1.removeLast());
System.out.println(list1);
}
}
案例:
请用LinkedList模拟栈数据结构的集合,并测试(栈:先进后出)
定义类:MyStack类
package day13;
import java.util.LinkedList;
public class MyStack {
private LinkedList linkedList;
// public MyStack(LinkedList linkedList) {
// this.linkedList = linkedList;
// }
public MyStack() {
linkedList = new LinkedList();
}
public void Add(Object obj){
linkedList.addFirst(obj);
}
public int stackSize(){
return linkedList.size();
}
public Object getObject(){
//return linkedList.getFirst();错误:模拟的是栈,栈中的内容弹出后不会留下值,所以不是get方法,要用remove方法,同步删除数据
return linkedList.removeFirst();
}
@Override
public String toString() {
return "MyStack{" +
"linkedList=" + linkedList +
'}';
}
}
测试类:LinkedListTest1类
package day13;
/*
LinkedList
请用LinkedList模拟栈数据结构的集合,并测试
栈:先进后出
题目的要求是:自己创建一个类,将LinkedList作为成员变量,将来创建自己的类对象,使用自己的方法,但是底层用的是LinkedList中的方法
*/
public class LinkedListTest1 {
public static void main(String[] args) {
// LinkedList list1 = new LinkedList();
//
// list1.add("hello");
// list1.add("world");
// list1.add("java");
// list1.add("hadoop");
// System.out.println("list1: " + list1);
//
// System.out.println("----------------------------------");
// for (int i = list1.size() - 1; i >= 0; i--) {
// System.out.println(list1.remove(i));
// }
/*
如果按照上面的做法解题,0分。
*/
MyStack myStack = new MyStack();
myStack.Add("hello");
myStack.Add("world");
myStack.Add("java");
myStack.Add("hadoop");
System.out.println(myStack);
System.out.println("===========================");
for (int i = myStack.stackSize() - 1; i >= 0; i--) {
System.out.println(myStack.getObject());
}
}
}
七、增强for的概述及使用
语句定义格式:
for(元素的类型 变量名 : Collection集合|数组){
直接使用变量,就相当于使用元素
}
注意事项:
1. 增强for循环本质用来替代迭代器的
2. 数组也蹭了增强for循环的光
package day14;
import java.util.ArrayList;
import java.util.Iterator;
public class ForDemo1 {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();//自动类型推断
list1.add("hello");
list1.add("world");
list1.add("java");
list1.add("hadoop");
list1.add("hello");
list1.add("java");
//方式1:转数组遍历
Object[] array = list1.toArray();
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
System.out.println("===========================");
//方式2:迭代器遍历
Iterator<String> iterator = list1.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("==============================");
//方式3:for循环,因为List集合有索引,所以有第三中方式遍历,使用size()和get()
for (int i = 0; i < list1.size(); i++) {
System.out.println(list1.get(i));
}
System.out.println("======================================");
/*
* 方式4:使用增强for循环遍历Collection集合或数组,增强for循环本质是用来替代迭代器的
*
* 语句定义格式:
* for(元素的类型 变量名:Collection集合|数组){
* 直接使用变量,就相当于使用元素
* }
*
* 注意事项:
* 1、增强for循环本质用来替代迭代器的
* 2、数组也可以使用增强for循环的功能
* */
// for(String s: list1){
// if ("java".equals(s)){//
// list1.add("xxxxx");
// }
// System.out.println(s);
// }
System.out.println("============================");
String[] arr = {"das","daeqwes","hello","world"};
for(String s: arr){
System.out.println(s);
}
System.out.println("====================================");
list1.forEach(System.out::println); // lambda表达式的简化写法
// list1.forEach((e)->{
// String upperCase = e.toUpperCase();
// System.out.println(upperCase);
// });
}
}
八、可变参数概述及使用
可变参数:
在方法定义的时候,指名该方法某个数据类型可以传入若干个
注意:
Java中方法的可变参数只能定义在最后一个,一个方法只能有一个可变参数
package day14;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
public class CanshuDemo1 {
public static void main(String[] args) {
//需求1:定义一个方法,求两个int类型元素和
System.out.println(sum(10,20));
//需求2:定义一个方法,求三个int类型元素的和
System.out.println(sum(10, 20, 30));
//需求3: 定义一个方法,求四个int类型元素的和
System.out.println(sum(10, 20, 30, 40));
//需求4: 定义一个方法,求五个int类型元素的和
System.out.println(sum(10, 20, 30, 40, 50));
//需求5: 现在有一个姓名字符串和若干个分数,求该学生的总分
fun1("张三", 98, 90, 10);
// fun2(98, 90, 10, "魏一民");
}
// public static void fun1(int... scores,String name) {
// int sum = 0;
// for (int i : scores) {
// sum += i;
// }
// System.out.println(name + "的考试总分为: " + sum);
// }
public static void fun1(String name, int... scores) {
int sum = 0;
for (int i : scores) {
sum += i;
}
System.out.println(name + "的考试总分为: " + sum);
}
public static int sum(int... ints){
//int... 表示方法调用时可以传入若干个int类型的元素
//ints是用来可变参数的
//可变参数传入的值被封装到一个数组中了,这个数组的名字就是参数名
int sum = 0;
for(int i : ints){
sum += i;
}
return sum;
}
// public static int sum(int a, int b, int c, int d) {
// return a + b + c + d;
// }
//
// public static int sum(int a, int b, int c) {
// return a + b + c;
// }
//
// public static int sum(int a, int b) {
// return a + b;
// }
}
九、静态导入
静态导入:前提使用的方法是静态的
package day14;
/*
静态导入: 前提使用的方法是静态的
*/
public class StaticImportDemo1 {
public static void main(String[] args) {
// System.out.println(Math.max(10,45));
// System.out.println(Math.max(312,45));
// System.out.println(Math.max(2,24));
// System.out.println(Math.max(13,512));
System.out.println(max(213,634));
System.out.println(java.lang.Math.max(213,3));
System.out.println(Math.max(213,52));
// System.out.println(max(81,234));
//
// System.out.println(min(232,51));
}
//使用的是自己的
public static int max(int a,int b){
System.out.println("这是我们自己写的。。。。。。");
System.out.println("a是b的第一个参数");
return 0;
}
}
十、Set接口概述
特点:元素唯一且无序
1、HashSet类
使用Set集合存储自定义对象,当对象的姓名和年龄都一样的时候,将这两个对象认为是重复了,进行去重
HashSet:底层数据结构是哈希表
案例:
Student类:
package day14;
import java.util.Objects;
public class Student1 {
private String name;
private int age;
public Student1() {
}
public Student1(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 "Student1{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student1 student1 = (Student1) o;
return age == student1.age && Objects.equals(name, student1.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
SetDemo2类
package day14;
import day14.Student1;
import java.util.HashSet;
public class SetDemo2 {
public static void main(String[] args) {
//创建一个Set集合对象
HashSet<Student1> set1 = new HashSet<>();
//创建元素对象
Student1 s1 = new Student1("张三", 18);
Student1 s2 = new Student1("李四", 18);
Student1 s3 = new Student1("王五", 16);
Student1 s4 = new Student1("张三", 18);
Student1 s5 = new Student1("赵六", 15);
//向集合中添加元素
set1.add(s1);
set1.add(s2);
set1.add(s3);
set1.add(s4);
set1.add(s5);
//遍历集合
for(Student1 student1: set1){
System.out.println(student1);
}
}
}
LinkedHashSet(底层数据结构是哈希表和双链表)
package day14;
import java.util.LinkedHashSet;
/*
LinkedHashSet是继承自HashSet类, 底层数据结构是哈希表和双链表,哈希表保证了元素的唯一性,双链表保证了元素的有序
Collection: 接口
- List(元素有序且可以发生重复,且有索引的概念)
- ArrayList(底层数据结构是数组,查询快,增删慢,线程不安全,效率高)
- Vector(底层数据结构是数组,查询快,增删慢,线程安全的,效率低,即便是安全的,我们以后也不使用)
- LinkedList(底层数据结构是双链表,增删快,查询慢,线程不安全,效率高)
- Set(元素唯一且无序,没有索引)
- HashSet(底层数据结构是哈希表)
- LinkedHashSet(底层数据结构是哈希表和双链表)
*/
public class LinkedHashSetDemo1 {
public static void main(String[] args) {
LinkedHashSet<String> set1 = new LinkedHashSet<>();
set1.add("hello");
set1.add("world");
set1.add("hello");
set1.add("java");
set1.add("hello");
set1.add("hadoop");
set1.add("spark");
set1.add("hello");
System.out.println("set1: " + set1);
}
}
为什么HashSet中add方法会产生去重,且输出是无序的
HashSet中add方法源码解释
// 结论1: HashSet中的add方法底层实际上调用的是HashMap中的put方法
// 结论2: 观察HashMap中put方法源码后发现,底层调用了元素类中的hashCode()方法
// 结论3: 底层判断元素是否已经存在的方式是,判断待添加元素的hashCode()方法和equals()方法的结果是否与已经存在集合中元素的hashCode()方法和equals()方法的结果一样
// 若一样,就进行去重,若不一样,就将待插入的元素添加到集合中
// 我们自己定义的Student类中并没有写hashCode()方法和equals()方法,所以底层调用都是该类的父类Object中的hashCode()方法和equals()方法,比较的都是地址值
// 而每一个元素对象都是单独new出来的,所以比较的结果永远是比较地址值,永远是false
// 我们要想比较内容的话,应该在元素类中重写父类Object类中的hashCode()方法和equals()方法, 自动生成即可
/*
Student s1 = new Student("张三", 18);
set1.add(s1);
*/
class HashSet{
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
public boolean add(E e) {
// E - Student
// e - s1
return map.put(e, PRESENT)==null;
}
}
class HashMap{
public V put(K key, V value) {
// key - s1
// value - new Object()
return putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
Node<K,V>[] tab; // null
Node<K,V> p; // null
int n; // 0
int i; // 0
//初始化hash table
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//将第一个元素当作哈希表的第一个节点
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
// 从第二个元素做添加的时候,走这里
else {
Node<K,V> e;
K k; // null
if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
// 将新增的元素封装成一个节点放入到集合中
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
}
2、TreeSet类
TreeSet(底层数据结构是红黑树,自己指定排序方式)
两种排序方式:
1.自然排序
2.比较器排序
思考:使用TreeSet存储自定义学生对象,按照年龄从大到小排序,且去重
基本用法:
package day14;
import java.util.TreeSet;
public class TreeSetDemo1 {
public static void main(String[] args) {
TreeSet<String> set1 = new TreeSet<>();
set1.add("hello");
set1.add("world");
set1.add("hello");
set1.add("java");
set1.add("hello");
set1.add("hadoop");
set1.add("spark");
set1.add("hello");
set1.add("apple");
System.out.println("set1:"+set1);
}
}
练习:使用TreeSet存储自定义学生对象,按照年龄从小到大排序,且去重
自定义Student类
package day14;
public class Student2 implements Comparable<Student2> {
private String name;
private int age;
public Student2() {
}
public Student2(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 "Student2{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student2 o){
int i = this.age - o.age;
return(i==0)?this.name.compareTo(o.name):i;
}
}
测试类TreeSetDemo2类
package day14;
import java.util.TreeSet;
/*
使用TreeSet存储自定义学生对象,按照年龄从小到大排序,且去重
若创建TreeSet对象是无参构造方法的话,底层创建TreeMap无参构造方法创建的,comparator = null;走的自然排序
*/
public class TreeSetDemo2 {
public static void main(String[] args) {
//创建TreeSet的集合对象
TreeSet<Student2> set1 = new TreeSet<>();
//创建元素对象
Student2 s1 = new Student2("张三", 18);
Student2 s2 = new Student2("李四", 18);
Student2 s3 = new Student2("王五", 16);
Student2 s4 = new Student2("张三", 18);
Student2 s5 = new Student2("赵六", 15);
//添加元素
set1.add(s1);
set1.add(s2);
set1.add(s3);
set1.add(s4);
set1.add(s5);
//遍历集合
for (Student2 student2 : set1) {
System.out.println(student2);
}
}
}
TreeSet的比较器排序
通过观察源码发现想要使用比较器排序,就要保证TreeMap中的comparator参数不是null,要想保证TreeMap中的comparator参数不是null,就得使用TreeMap有参构造方法来创建,就要保证在创建TreeSet对象的时候,传入一个实现了Comparator的对象
package day14;
import java.util.Comparator;
import java.util.TreeSet;
/*
TreeSet的比较器排序
通过观察源码发现.要想使用比较器排序,就得保证TreeMap中的comparator参数不是null,
要想保证TreeMap中的comparator参数不是null,就得使用TreeMap有参构造方法来创建,就要保证在创建TreeSet对象的时候
,传入一个实现了Comparator的对象
*/
//class ComparatorImpl implements Comparator<Student3>{
// @Override
// public int compare(Student3 o1, Student3 o2) {
// //cpr.compare(key, t.key);
// // o1 - key - 待插入的元素
// // o2 - t.key - 根的元素
// //需求:按照年龄从小到大排序,并去重
// int i = o2.getAge() - o1.getAge();
// return (i==0)?o1.getName().compareTo(o2.getName()):i;
// }
//}
public class TreeSetDemo3 {
public static void main(String[] args) {
// TreeSet<Student3> set1 = new TreeSet<>(new ComparatorImpl());
TreeSet<Student3> set1 = new TreeSet<>(new Comparator<Student3>() {
@Override
public int compare(Student3 o1, Student3 o2) {
//cpr.compare(key, t.key);
// o1 - key - 待插入的元素
// o2 - t.key - 根的元素
//需求:按照年龄从小到大排序,并去重
int i = o2.getAge() - o1.getAge();
return (i == 0) ? o1.getName().compareTo(o2.getName()) : i;
}
});
//创建元素对象
Student3 s1 = new Student3("张三", 18);
Student3 s2 = new Student3("李四", 18);
Student3 s3 = new Student3("王五", 16);
Student3 s4 = new Student3("张三", 18);
Student3 s5 = new Student3("赵六", 15);
//添加元素
set1.add(s1);
set1.add(s2);
set1.add(s3);
set1.add(s4);
set1.add(s5);
//遍历集合
for (Student3 student : set1) {
System.out.println(student);
}
}
}
studen类:
package com.shujia.day14;
public class Student3 {
private String name;
private int age;
public Student3() {
}
public Student3(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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
TreeSet中的add方法源码解释
// 结论1: TreeSet调用的add方法底层是调用了TreeMap中的put方法进行添加元素的
/*
//创建一个TreeSet对象
TreeSet<String> set1 = new TreeSet<>();
*/
class TreeSet{
private transient NavigableMap<E,Object> m; // null
private static final Object PRESENT = new Object();
public TreeSet() {
this(new TreeMap<E,Object>()); // this(...)
}
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
TreeSet(NavigableMap<E,Object> m) {
this.m = m;
}
//set1.add("hello");
//set1.add("world");
public boolean add(E e) {
// E - String
// e - "world"
// PRESENT - new Object();
return m.put(e, PRESENT)==null;
}
}
class TreeMap{
private transient Entry<K,V> root; // null
public TreeMap() {
comparator = null;
}
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
public V put(K key, V value) {
// key - "world"
// value - new Object()
Entry<K,V> t = root; // 第一个元素添加的时候,树连根都没有,是null
if (t == null) {
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator; // null
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
else {
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key; // Student2
do {
parent = t; // "hello"
cmp = k.compareTo(t.key); // "world".compareTo("hello")
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
}
十一、Collections工具类
静态成员方法:
public static <T> void sort(List<T> list)
public static <T> int binarySearch(List<?> list,T key)
public static <T> T max(Collection<?> coll)
public static void reverse(List<?> list)
public static void shuffle(List<?> list)
package day15;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class CollectionsDemo {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
list1.add("hello");
list1.add("world");
list1.add("hadoop");
list1.add("apple");
System.out.println("list1: "+list1);
System.out.println("====================");
Collections.sort(list1);//对集合进行升序排序
System.out.println("list1: "+list1);
//list1: [apple, hadoop, hello, world]
//public static <T> int binarySearch(List<?> list,T key) 在针对List集合中二分查找某个元素,返回该元素的下标索引
System.out.println(Collections.binarySearch(list1,"hello"));
//public static <T> T max(Collection<?> coll)
System.out.println(Collections.max(list1));
//public static void reverse(List<?> list) 将集合元素反转
Collections.reverse(list1);
System.out.println("list1: "+list1);
//public static void shuffle(List<?> list) 将List集合元素进行随机打乱,每次运行结果都不一样
Collections.shuffle(list1);
System.out.println("list1: "+list1);
//即便Vector是线程安全的,我们今后也不用
//原因是我们可以通过Collections工具类对ArrayList或其他不安全的集合做操作,变成安全的。
List<String> list2 = Collections.synchronizedList(list1);
//后续用list2,跟不安全的用法一毛一样,没有任何区别,只是后续这个List集合是安全的了。
}
}
十二、Map接口
Map:存储元素的特点是每一个元素是一个键对值{【key:12】,【value:10000】}
Map集合的共同拥有的特点:
- Map集合中的元素,键是唯一的,不会在一个Map集合发现两个相同的键
- Map集合中,值是可以发生重复的
- Map集合的唯一性,排序都是针对键来说的,值是跟着键走的
Map接口中的成员方法:
V put(K key,V value)
V remove(Object key)
void clear()
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean isEmpty()
int size()
package day15;
import java.util.HashMap;
import java.util.Map;
public class MapDemo1 {
public static void main(String[] args) {
//创建一个Map对象
Map<Integer,String> map1 = new HashMap<>();
//V put(K key,V value) 向集合中添加键值对元素 返回的是被覆盖的键对应的那个值
System.out.println(map1.put(1001, "张三"));
System.out.println(map1.put(1002, "李四"));
System.out.println(map1.put(1003, "王五"));
System.out.println(map1.put(1001, "赵六")); // 会将上面1001键的值进行覆盖操作
System.out.println(map1.put(1004, "孙七"));
System.out.println("map1: "+map1);
System.out.println("----------------------------------");
//V remove(Object key) 根据键删除一个键值对元素 返回被删除键值对的值
// System.out.println(map1.remove(1001));
// System.out.println("map1: "+map1);
// System.out.println("----------------------------------");
//void clear()
// map1.clear();
// System.out.println("map1: "+map1);
// System.out.println("----------------------------------");
//boolean containsKey(Object key) 判断键是否存在
System.out.println(map1.containsKey(1001));
System.out.println("----------------------------------");
//boolean containsValue(Object value) 判断值是否存在
System.out.println(map1.containsValue("孙七"));
System.out.println("----------------------------------");
//boolean isEmpty()
System.out.println(map1.isEmpty());
System.out.println("----------------------------------");
//int size() 获取集合中的键值对的个数
System.out.println(map1.size());
}
}
Map集合的遍历
遍历方式:
方式1:先一次性获取所有的键,遍历键根据键找到值
方式2:可以拿到每一键对值组成的一个对象,遍历这个对象中的元素得到每一个键值对中 的键值和。
package day15;
import javax.swing.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/*
map集合的遍历
遍历方式:
方式1:先一次性获取所有的键,遍历键根据键找到值。
方式2:可以拿到每一键值对组成的一个对象,遍历这个对象中的元素得到每一个键值对中的键和值。
*/
public class MapDemo2 {
public static void main(String[] args) {
//创建一个Map对象
Map<Integer,String> map1 = new HashMap<>();
//V put(K key,V value)向集合中添加键对值元素,返回的是被覆盖的键对应的那个值
System.out.println(map1.put(1001, "张三"));
System.out.println(map1.put(1004, "李四"));
System.out.println(map1.put(1003, "王五"));
System.out.println(map1.put(1001, "赵六")); // 会将上面1001键的值进行覆盖操作
System.out.println(map1.put(1002, "孙七"));
System.out.println("map1: "+map1);
System.out.println("===================================");
//方式一:先一次性获取所有的键,遍历键根据键找到值
//keySet()获取map集合所有的键,返回所有的键组成的一个Set集合
Set<Integer> keys = map1.keySet();
for(Integer key: keys){
String value = map1.get(key);
System.out.println(key + "-" + value);
}
System.out.println("---------------------------------");
//方式二:可以拿到每一个键值组成的一个对象,遍历这个对象中的元素得到每一个键值对中的键和值
//entrySet() 获取每一个键值对,组成一个Set集合
Set<Map.Entry<Integer,String>> entries = map1.entrySet();
for (Map.Entry<Integer,String>entry : entries){
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"-"+value);
}
}
}
十三、HashMap类(Map接口)
HashMap <Student2,String>
这里的话,我们认为当学生的姓名和年龄一样的时候,认为是重复的
如果有一个自定义类型当作键的类型的时候,想要保证唯一性,就需要元素重写hashCode()和equals()方法
自定义student类:
package day15;
import java.util.Objects;
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
}
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;
}
@Override //重写的
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override //重写的
public int hashCode() {
return Objects.hash(name, age);
}
@Override //接口重写的
public int compareTo(Student o) {
int i = this.age - o.age;
return (i==0)?this.name.compareTo(o.name):i;
}
}
测试HashMapDemo1类:
package day15;
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo1 {
public static void main(String[] args) {
HashMap<Student,String> map1 = new HashMap<>();
map1.put(new Student("张三",18),"跳舞");
map1.put(new Student("李四",17),"美女");
map1.put(new Student("王五",18),"篮球");
map1.put(new Student("赵六",19),"rap");
map1.put(new Student("孙七",17),"美女");
Set<Student> student2s = map1.keySet();
for (Student student2 : student2s) {
System.out.println(student2);
}
}
}
面试题:HashMap和Hashtable的区别
区别1:HashMap中的键和值都允许为null值,Hashtable的键和值都不允许null
区别2:HashMap是线程不安全的,Hashtable是线程安全的,因为它的方法基本都有synchronized
package day15;
import java.util.HashMap;
import java.util.Hashtable;
/*
面试题:HashMap和Hashtable的区别
区别1:HashMap中的键和值都允许为null值,Hashtable的键和值都不允许null
区别2:HashMap是线程不安全的,Hashtable是线程安全的,因为它的方法基本都有synchronized
*/
public class HashMapDemo2 {
public static void main(String[] args) {
HashMap<String, String> map1 = new HashMap<>();
// map1.put(null,"qwe");
// map1.put(null,null);
// map1.put("qwerwqr",null);
Hashtable<String, String> map2 = new Hashtable<>();
// map2.put(null,"qwe");
// System.out.println(map2);
// map2.put("zxc",null);
}
}
十四、LinkedHashMap类(Map接口)
格式:
public class LinkedHashMap extends HashMap{}
底层数据结构是哈希表和链表
package day15;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Set;
/*
class LinkedHashMap extends HashMap{}
底层数据结构是哈希表和链表
*/
public class LinkedHashMapDemo1 {
public static void main(String[] args) {
LinkedHashMap<Integer, String> map1 = new LinkedHashMap<>();
// HashMap<Integer, String> map1 = new HashMap<>();
map1.put(1001, "张三");
map1.put(1008, "李四");
map1.put(1006, "王五");
map1.put(1001, "赵六");
map1.put(1004, "孙七");
System.out.println("map1: "+map1);
}
}
十五、TreeMap类
package day15;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapDemo1 {
public static void main(String[] args) {
TreeMap<Student2, String> map1 = new TreeMap<>();
map1.put(new Student2("a1", 15), "唱歌");
map1.put(new Student2("a5", 19), "跳舞");
map1.put(new Student2("a1", 15), "rap");
map1.put(new Student2("a2", 12), "打篮球");
map1.put(new Student2("a4", 17), "打游戏");
Set<Student2> student2s = map1.keySet();
for (Student2 student2 : student2s) {
String value = map1.get(student2);
System.out.println(student2 + "-" + value);
}
}
}
十六、练习
-- 1、"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
-- 2、ArrayList嵌套HashMap
-- 3、键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
-- 4、获取10个1-20之间的随机数,要求不能重复
-- 5、使用List和Map存放多个图书信息,遍历并输出。其中商品属性:编号,名称,单价,出版社;使用商品编号作为Map中的key。
-- 6、使用HashSet和TreeSet存储多个商品信息,遍历并输出;其中商品属性:编号,名 称,单价,出版社;要求向其中添加多个相同的商品,验证集合中元素的唯一性。
提示:
向HashSet中添加自定义类的对象信息,需要重写hashCode和equals( )
向TreeSet中添加自定义类的对象信息,需要实现Comparable接口,指定比较规则
-- 7、实现List和Map数据的转换。具体要求如下:
功能1:定义方法public void listToMap( ){ }将List中Student元素封装到Map中
功能2:定义方法public void mapToList( ){ }将Map中Student映射信息封装到List
-- 8、 假如有以下email数据“aa@sohu.com,bb@163.com,cc@sina.com,.. ”现需要把email 中的用户部分和邮件地址部分分离,分离后以键值对应的方式放入HashMap?
-- 9、由控制台按照固定格式输入学生信息,包括学号,姓名,年龄信息,当输入的内容 为exit退出;将输入的学生信息分别封装到一个Student对象中,再将每个Student 对象加入到一个集合中,要求集合中的元素按照年龄大小正序排序;
十七、答案
-- 1、"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
package day15.HomeWork6;
import sun.reflect.generics.tree.Tree;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class HomeWorkTest6 {
public static void main(String[] args) {
String s = "aababcabcdabcde";
TreeMap<Character,Integer>map1 = new TreeMap<>();
char[] chars = s.toCharArray();
for(char c:chars){
//将字符作为键存储在Map集合中
//先判断集合中是否有该建、若没有,就赋值该字符为键,1为值存储【c,1】
//若集合已经存在该键了,在原来键对应的值基础之上加一【c,1】->【c,2】
if(!map1.containsKey(c)){
map1.put(c,1);
}else{
map1.put(c,map1.get(c)+1);
}
}
StringBuilder stringBuilder = new StringBuilder();
Set<Map.Entry<Character,Integer>> entries = map1.entrySet();
for(Map.Entry<Character,Integer>entry:entries){
Character key = entry.getKey();
Integer value = entry.getValue();
stringBuilder.append(key).append("(").append(value).append(")");
}
String Set = stringBuilder.toString();
System.out.println(Set);
}
}
-- 2、ArrayList嵌套HashMap
package day15.HomeWork7;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HomeWorkTest7 {
public static void main(String[] args) {
ArrayList<HashMap<Integer,String>> list = new ArrayList<>();
HashMap<Integer,String> map1 = new HashMap<>();
map1.put(1001,"小张");
map1.put(1002,"小李");
map1.put(1003,"小王");
HashMap<Integer,String> map2 = new HashMap<>();
map2.put(1004,"小张1");
map2.put(1005,"小李1");
map2.put(1006,"小王1");
HashMap<Integer,String> map3 = new HashMap<>();
map3.put(1007,"小张2");
map3.put(1008,"小李2");
map3.put(1009,"小王2");
list.add(map1);
list.add(map2);
list.add(map3);
for(HashMap<Integer, String> map:list){
System.out.println("====================================");
Set<Map.Entry<Integer,String>> entries = map.entrySet();
for(Map.Entry<Integer,String>entry:entries){
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"|"+value);
}
}
}
}
-- 3、键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
Student类:
package day15.HomeWork8;
public class Student {
private String name;
private int chinese;
private int math;
private int english;
public Student() {
}
public Student(String name, int chinese, int math, int english) {
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
public int getSum(){
return chinese + math + english;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", chinese=" + chinese +
", math=" + math +
", english=" + english +
'}';
}
}
测试类:
package day15.HomeWork8;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
public class HomeWorkTest8 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
TreeSet<Student>set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//显示条件:
int i = o2.getSum()- o1.getSum();
//隐式条件:
//总分一样,各科的分数不一定一样
//总分一样,语文成绩不一定一样
int i2 = (i==0)? o2.getChinese() - o1.getChinese():i;
//总分,语文成绩一样,数学成绩不一定一样
int i3 = (i2==0)? o2.getMath() - o1.getMath():i2;
//各科分数一样,姓名不一定一样
return (i3==0)? o2.getName().compareTo(o1.getName()):i3;
}
});
Student student;
for (int i = 1; i <= 5; i++) {
System.out.println("请输入第 "+i+" 个学生的信息:");
System.out.print("姓名:");
String name = sc.next();
System.out.print("语文成绩:");
int chinese = sc.nextInt();
System.out.print("数学成绩:");
int math = sc.nextInt();
System.out.print("英语成绩:");
int english = sc.nextInt();
//创建一个学生对象,将当前学生的信息进行封装
student = new Student(name,chinese,math,english);
//将学生对象添加到集合中
set.add(student);
System.out.println("----------------------------------------------------------");
}
for (Student student1 : set) {
System.out.println(student1.getName()+"\t\t"+student1.getChinese()+"\t\t"+student1.getMath()+"\t\t"+student1.getEnglish()+"\t\t"+student1.getSum());
}
}
}
-- 4、 获取10个1-20之间的随机数,要求不能重复
/*
分析:
1.创建一个空的List集合
2、因为生成随机数是可能发生重复的,所以生成随机数的次数是不确定的,采用while循环
3、每次生成一个数字,判断集合是否存在,若不存在,就添加到集合中,次数加一,反之继续循环
4、直到次数为10的时候,跳出循环,生成完毕。
*/
package day14.HomeWork;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class HomeWork01 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
Random r = new Random();
int count=0;
int num=0;
while(count<10){
int number = r.nextInt(20)+1;
if(!list.contains(number)){
list.add(number);
count++;
}
num++;
}
System.out.println(list +"|"+num);
}
}
-- 5、使用List和Map存放多个图书信息,遍历并输出。其中商品属性:编号,名称,单价,出版社;使用商品编号作为Map中的key。
Goods类:
package day15.HomeWork1;
public class Goods {
private String Id;
private String name;
private double price;
private String publisher;
public Goods() {
}
public Goods(String id, String name, double price, String publisher) {
Id = id;
this.name = name;
this.price = price;
this.publisher = publisher;
}
public String getId() {
return Id;
}
public void setId(String id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
@Override
public String toString() {
return "Goods{" +
"Id='" + Id + '\'' +
", name='" + name + '\'' +
", price=" + price +
", publisher='" + publisher + '\'' +
'}';
}
}
测试类:
package day15.HomeWork1;
import java.util.*;
public class HomeWorkTest1 {
public static void main(String[] args) {
Goods book1 = new Goods("1001","红岩",12.0,"人民出版社");
Goods book2 = new Goods("1002","苦难辉煌",18.5,"商务出版社");
Goods book3 = new Goods("1003","浮士德",55.0,"译林出版社");
//第一种要求,使用List存放图书信息
List<Goods> commodity1 = new ArrayList<>();
commodity1.add(book1);
commodity1.add(book2);
commodity1.add(book3);
for(Goods books:commodity1){
System.out.println(books);
}
System.out.println("----------------------------------------------------");
//第二种要求,使用Map存放图书信息
Map<String,Goods> commodity2 = new HashMap<>();
commodity2.put(book1.getId(), book1);
commodity2.put(book2.getId(), book2);
commodity2.put(book3.getId(), book3);
Set<Map.Entry<String,Goods>> books = commodity2.entrySet();
for (Map.Entry<String,Goods> book:books){
String key = book.getKey();
Goods value = book.getValue();
System.out.println(value);
}
}
}
-- 6、使用HashSet和TreeSet存储多个商品信息,遍历并输出;其中商品属性:编号,名称,单价,出版社;要求向其中添加多个相同的商品,验证集合中元素的唯一性。
commodity类:
package day15.HomeWork2;
import java.util.Objects;
public class commodity implements Comparable<commodity> {
private int ID;
private String name;
private double price;
private String publisher;
public commodity() {
}
public commodity(int ID, String name, double price, String publisher) {
this.ID = ID;
this.name = name;
this.price = price;
this.publisher = publisher;
}
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
@Override
public String toString() {
return "commodity{" +
"ID='" + ID + '\'' +
", name='" + name + '\'' +
", price=" + price +
", publisher='" + publisher + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
commodity commodity = (commodity) o;
return price == commodity.price && Objects.equals(ID, commodity.ID) && Objects.equals(name, commodity.name) && Objects.equals(publisher, commodity.publisher);
}
@Override
public int hashCode() {
return Objects.hash(ID, name, price, publisher);
}
@Override
public int compareTo(commodity o) {
return this.ID-o.ID;
}
}
测试类:
package day15.HomeWork2;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
public class HomeWorkTest2 {
public static void main(String[] args) {
//创建对象元素
commodity book1 = new commodity(1001,"红岩",12.0,"人民出版社");
commodity book2 = new commodity(1002,"苦难辉煌",18.5,"商务出版社");
commodity book3 = new commodity(1003,"浮士德",55.0,"译林出版社");
//创建集合对象,按照要求一,使用HashSet存储数据
Set<commodity> information1 = new HashSet<>();
//添加元素对象
information1.add(book1);
information1.add(book2);
information1.add(book3);
for(commodity book: information1){
System.out.println(book);
}
System.out.println("======================================");
//按照需求而使用TreeHash排序,使用自然排序
Set<commodity> information2 = new TreeSet<>();
information2.add(book1);
information2.add(book2);
information2.add(book3);
for(commodity book: information2){
System.out.println(book);
}
}
}
-- 7、实现List和Map数据的转换。具体要求如下:
功能1:定义方法public void listToMap( ){ }将List中Student元素封装到Map中
功能2:定义方法public void mapToList( ){ }将Map中Student映射信息封装到List
Student类:
package day15.HomeWork3;
public class Student {
private int Id;
private String name;
private int age;
private String sex;
public Student() {
}
public Student(int id, String name, int age, String sex) {
Id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"Id=" + Id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
测试类:
package day15.HomeWork3;
import java.util.*;
public class HomeWorkTest3 {
public void listToMap(){
List<Student> students = new ArrayList<>();
//创建元素对象
Student student1 = new Student(1001,"小张",18,"男");
Student student2 = new Student(1002,"小李",17,"男");
Student student3 = new Student(1003,"小王",14,"男");
Student student4 = new Student(1004,"小赵",19,"女");
Student student5 = new Student(1005,"小孙",18,"女");
students.add(student1);
students.add(student2);
students.add(student3);
students.add(student4);
students.add(student5);
for(Student student:students){
System.out.println(student);
}
System.out.println("====================================");
Map<Integer,Student> map1 = new HashMap<>();
for(Student student:students){
map1.put(student.getId(),student);
}
Set<Map.Entry<Integer,Student>> entries = map1.entrySet();
for(Map.Entry<Integer,Student> entry: entries){
System.out.println(entry.getValue());
}
}
public void mapToList(){
Map<Integer,Student>map = new HashMap<>();
//创建元素对象
Student student1 = new Student(1001,"小张1",18,"男");
Student student2 = new Student(1002,"小李1",17,"男");
Student student3 = new Student(1003,"小王1",14,"男");
Student student4 = new Student(1004,"小赵1",19,"女");
Student student5 = new Student(1005,"小孙1",18,"女");
map.put(student1.getId(), student1);
map.put(student2.getId(), student2);
map.put(student3.getId(), student3);
map.put(student4.getId(), student4);
map.put(student5.getId(), student5);
List <Student>students = new ArrayList<>();
Set<Map.Entry<Integer,Student>> entries = map.entrySet();
for(Map.Entry<Integer,Student> entry:entries){
students.add(entry.getValue());
}
for(Student stu:students){
System.out.println(stu);
}
}
public static void main(String[] args) {
HomeWorkTest3 hw3 = new HomeWorkTest3();
hw3.listToMap();
System.out.println("-----------------------------------------------");
hw3.mapToList();
}
}
-- 8、假如有以下email数据“aa@sohu.com,bb@163.com,cc@sina.com,.. ”现需要把email 中的用户部分和邮件地址部分分离,分离后以键值对应的方式放入HashMap?
package day15.HomeWork4;
import com.sun.crypto.provider.HmacPKCS12PBESHA1;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HomeWorkTest4 {
public static void main(String[] args) {
String email = "aa@sohu.com,bb@163.com,cc@sina.com";
String[] email1 = email.split(",");
Map<String,String> map = new HashMap<>();
for (String s : email1) {
String[] tmp = s.split("@");
map.put(tmp[0], tmp[1]);
}
Set<Map.Entry<String,String>> entries = map.entrySet();
for(Map.Entry<String,String>entry:entries){
System.out.println(entry.getKey()+"--"+entry.getValue());
}
}
}
-- 9、由控制台按照固定格式输入学生信息,包括学号,姓名,年龄信息,当输入的内容 为exit退出;将输入的学生信息分别封装到一个Student对象中,再将每个Student 对象加入到一个集合中,要求集合中的元素按照年龄大小正序排序
Student类:
package day15.HomeWork5;
public class Student implements Comparable<Student>{
private Integer Id;
private String name;
private Integer age;
public Student() {
}
public Student(Integer id, String name, Integer age) {
Id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return Id;
}
public void setId(Integer id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"Id=" + Id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
return this.age - o.age;
}
}
测试类:
package day15.HomeWork5;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class HomeWorkTest5 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Set<Student> students = new TreeSet<>();
while(true){
System.out.println("输入(格式:编号#姓名#年龄):");
String stu = sc.nextLine();
if(stu.equals("exit")){
break;
}else{
String[] stu1 = stu.split("#");
Student student = new Student(Integer.parseInt(stu1[0]),stu1[1],Integer.parseInt(stu1[2]));
students .add(student);
}
}
for(Student stu:students){
System.out.println(stu);
}
}
}