java-Collections工具类,Set Map接口,斗地主排序升级版
补充:泛型接口
子类实现泛型接口的时候,有三种方式
1.实现类丢弃泛型
class Zi implements A{
public void show(Object o){
}
}
2.实现类在实现接口时候指定具体反省类型
class Zi implements A {
public void show(String s){}
}
3.实现类延续接口泛型
class Ziimplements A{
public void show(T t){}
}
泛型通配符:
匹配任何累类型:<?>
匹配规定类型的本身以及其子类<? extends A>
匹配规定类型的本身以及其父类<? super A>
Collection 工具类
1.java.util.Collection类:是一个对Collection集合(List、Set)操作的工具类,里面提供了大量的静态方法,可以对集合进行打印,查找和排序。
1.1常用方法
1.public static void shuffle(List<?> list):打乱集合顺序。
2.public static<T extends Comparable<? super T>>:对集合元素按照自然排序规则进行排序。
3.public staticvoid sort(Listlist,Comparator<? super >c>):对集合按照比较器规则进行排序。
1.2 sort方法自排序
1.自排序:
public static <T extends Comparable<? super T>>void sort(Listlist):对集合元素按照自然排序规则进行排序,要求集合元素必须实现Comparable 接口冰重写comparaTo方法。
2.ComparaTo()方法
comparaTo返回的是一个int,三种情况:
正数:当前对象大于参数对象
负数:当前对象小于参数对象
0: 当前对象等于参数对象
3.String类以及自定义类对象集合排序:
package com.day06.Collections_sort方法自排序;
import java.util.Objects;
public class Student implements Comparable<Student> {
private int age;
public Student() {
}
public Student(int age) {
this.age = age;
}
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;
}
@Override
public int hashCode() {
return Objects.hash(age);
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
return this.getAge() - o.getAge();//升序
//return o.getAge() - this.getAge();降序
}
}
*********************************************
package com.day06.Collections_sort方法自排序;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
//String 类型的排序
ArrayList<String> strList = new ArrayList<>();
String a = "n";
String b = "a";
strList.add(a);
strList.add(b);
Collections.sort(strList);
System.out.println(strList);
//自定义类
//1.自定义类必须实现Comparable类,并且改写comparaTO方法
ArrayList<Student> stuList = new ArrayList<>();
stuList.add(new Student(25));
stuList.add(new Student(28));
stuList.add(new Student(21));
Collections.sort(stuList);
System.out.println(stuList);
}
}
1.3 sort方法比较器排序(应用更方便)
public static void sort(List list ,Comparator<? super T>c):对集合按照比较器排序规则进行排序。
比较器排序的优先级要高于自排序
package com.day06.Collections_sort方法比较器排序;
import com.day06.Collections_sort方法自排序.Student;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
//String 的
ArrayList<String> strList = new ArrayList<>();
String a = "n";
String b = "a";
strList.add(a);
strList.add(b);
Collections.sort(strList, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
System.out.println(strList);
//基本类型封装类型,自排序对这些基本类型的只有升序,所以,需要降序或者其他排序方式,用这个方法。
//并且,比较器排序的优先级要高于自排序
ArrayList<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(12);
intList.add(10);
intList.add(19);
Collections.sort(intList, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;//升序
//return o2-o1;
}
});
//自定义类型 自定义类不需要实现Comparable类。
ArrayList<Student> stuList = new ArrayList<>();
stuList.add(new Student(25));
stuList.add(new Student(2589));
stuList.add(new Student(252));
Collections.sort(stuList, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()- o2.getAge();
}
});
}
}
练习:初始化学生对象存入集合中,对集合进行排序,先按照年龄进行排序,如果年龄相同,则按照分数排序
package com.day06.Collections_sort_练习;
import com.day06.Collections_sort方法自排序.Student;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
//练习:初始化学生对象存入集合中,对集合进行排序,先按照年龄进行排序,如果年龄相同,则按照分数排序
ArrayList<Student> stuList = new ArrayList<>();
Student stu1 = new Student(25,15);
Student stu2 = new Student(22,15);
Student stu3 = new Student(25,18);
Student stu4 = new Student(21,1);
Student stu5 = new Student(28,10);
stuList.add(stu1);
stuList.add(stu2);
stuList.add(stu3);
stuList.add(stu4);
stuList.add(stu5);
Collections.sort(stuList, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int a =o1.getAge()-o2.getAge();
if(a==0){
int b = o1.getScore()-o2.getScore();
}
return a;
}
});
System.out.println(stuList);
}
}
可变参数
2.1可变参数的使用
确定类型,但是不确定数量的时候,可以使用
格式:数据类型 …数据名称 (意义等同于不确定长度的数组)
package com.day06.可变参数;
import com.day06.Collections_sort方法自排序.Student;
public class Test {
public static void main(String[] args) {
can(1,2,3);
int[] arr={1,2,3};
can(arr);
can();
//给拥有可变参数的方法定义实参时,可以使用规定类型的个体,也可以使用该类型数组.
//如果方法中只有一个形参,并且可变参数,调用方法时候可以不传参
}
public static void can(int...arr){
}
public static void can(Student...Sarr){//相当于int[] arr
}
public static void can(int a ,String b ,int...arr){
}
public static void can (int...arr,int b ){}// 报错,可变参数只能放在形参的最末尾定义,所以,一个方法中,只能够拥有一个可变参
}
Set集合
3.1特点
1.无序
2.不可以存储重复元素
3.不可以通过索引访问元素
Set集合没有新增方法,都是集成Collection集合方法
Set集合是一个接口。
Set 集合有多个子类,这里我们介绍其中的 java.util.HashSet 、 java.util.LinkedHashSet 、 java.util.TreeSet 这两个集合。
tips:Set集合取出元素的方式可以采用:迭代器、增强for。
3.2 Set集合HashSet存储字符串
HashSet保证 元素唯一性的方式依赖于: hashCode 与 equals 方法。
package com.day06.Set集合使用;
import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Set<String> strList = new HashSet<>();
strList.add("wo");
strList.add("ai");
strList.add("ni");
strList.add("haha");
strList.add("wo");
System.out.println(strList);//[haha, wo, ai, ni] 无序存储,取出顺序不确定,不能存储重复元素
}
}
3.3 Set集合HashSet存储自定义对象
存储自定义对象时,要求自定义对象必须重写hashCode和equals方法,会根据hashCode和equals方法判断元素是否重复。先调用对象的hashCode方法进行哈希值的判断,若哈希值相同,就会进行equals的判断。
package com.day06.Set集合使用.Set存储自定义参数;
import com.day06.Collections_sort方法自排序.Student;//该类重写了方法
import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Set<Student> studentSet = new HashSet<>();
studentSet.add(new Student(25,26));
studentSet.add(new Student(25,26));
studentSet.add(new Student(25,26));
System.out.println(studentSet);
}
}
Set集合,哈希表结构:
public in hashCode();返回该对象的哈希码值,返回对象内存地址的十进制数。
哈希表存储方式是数组加链表。先判断元素的哈希值,按照数组方式存储。如果哈希值相同,则按照链表方式存储,当链表长度大于8时,会自动转化成为红黑树存储方式。
图示见文章末尾
Set集合_LInkedHashSet的特点以及使用
内部采用的是哈希表+链表存储元素,在哈希表基础上,多了一条链表,此链表记录的是元素的存储的顺序,所以,LInkedHashSet是有序的。
package com.day06.Set集合使用.LinkedHashSet使用;
import java.util.Iterator;
import java.util.LinkedHashSet;
public class Test {
public static void main(String[] args) {
//除了有序以外,其余的使用方法和HashSet没区别
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("ni");
linkedHashSet.add("hao");
linkedHashSet.add("jaja");
linkedHashSet.add("ni");
linkedHashSet.add("ni");
System.out.println(linkedHashSet);
//迭代器遍历
Iterator<String> iterator = linkedHashSet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//增强for遍历
for (String s : linkedHashSet) {
System.out.println(s);
}
}
}
Set集合,TreeSet的特点和使用
内部采用的是红黑树(平衡二叉树),要求元素有顺序,可以进行排序的。要求元素实现comparable接口并且重写comparaTo方法。
使用方面和HashSet一样,只不过是有顺序。
Map集合(双列集合)
数据结构都是作用在Key上的
**HashMap:**内部采用哈希表结构存储key,是通过hashcode和equals方法来判断key是否是重复的,要求key必须要重写hashcode和queals方法。
**LInkedHashMap:**内部采用的是哈希表加上链表存储结构存储key,在哈希表基础上多了一条链表,此链表记录的是key的存放顺序,所以LinkHashMap的key是有序的
**TreeMap:**内部采用红黑树(平衡二叉树)的结构存储key,要求key是可以进行排序的,所以key应该实现comparable接口,并且重写comparaTo方法。
Map集合基本操作:
package com.day06.Map使用;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<Integer,Integer> map = new HashMap<>();
//增加和修改
System.out.println(map.put(1,1));//NUll key=1的位置没有元素,所以返回null,相当于添加
System.out.println(map.put(1,2));//null,key1的位置上有元素,返回被覆盖的元素,相当于修改
//删除
System.out.println(map.remove(1));//删除key = 1的value(元素)和key
System.out.println(map.get(1));//查看key = 1位置上的元素
System.out.println(map.containsKey(1));//查看集合之中是否有为1的Key 返回值为布尔值
}
}
Map集合的两种遍历方式
1.键遍历
package com.day06.Map使用.键遍历;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Map<Integer,Integer> map = new HashMap<>();
//增加和修改
System.out.println(map.put(1,1));
System.out.println(map.put(2,2));
//键遍历
Set<Integer> keys = map.keySet();//创建一个Set集合keys,存储map的key
for (Integer key : keys) {
System.out.println(map.get(key));//将keys中的集合利用get方法遍历
}
}
}
2.键值对遍历 比键遍历效率更高!
package com.day06.Map使用.键值对遍历;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Map<Integer,Integer> map = new HashMap<>();
//增加和修改
System.out.println(map.put(1,1));
System.out.println(map.put(2,2));
//键值遍历
Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
for (Map.Entry<Integer, Integer> entry : entries) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
}
}
HashMap使用自定义对象做为键
内部采用的是哈希表数据结构存储key,要求自定义对象类必须重写equals()和hashCode()
LinkedHashMap
key有序,存取顺序一致。
TreeMap:
自定义对象作为key需要实现comparable接口并且重写comparaTo方法。因为有序
练习:计算每一个字符出现的次数
package com.day06.Map使用.计算每一个字符出现的顺序;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
String str = "abcbch";
Map<Character, Integer> map = new HashMap<>();
//获取每一个字符
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);//获取每一个字符
if (map.containsKey(c)) {//如果有此key
int count = map.get(c);//取出对应value 出现的次数
map.put(c, count + 1);
} else {
map.put(c, 1);
}
}
System.out.println(map);
}
}
斗地主排序版:
package com.day06.斗地主排序版;
import java.util.*;
public class Test {
public static void main(String[] args) {
//把每张牌,给予一个序号存入key,后续操作序号
Map<Integer,String> pukerMap = new HashMap<>();
int index = 0;
String[] huaSe = {"♥","♦","♠","♣",};
String[] paiMian = {"A","1","2","3","4","5","6","7","8","9","10","J","Q","K"};
pukerMap.put(index++,"大王");
pukerMap.put(index++,"小王");
for (String h : huaSe) {
for (String p : paiMian) {
pukerMap.put(index++,h+p);
}
}
ArrayList<Integer> pukerList = new ArrayList<>();
//将key存入pukerList 进行排序,发牌操作
Set<Integer> keys = pukerMap.keySet();
for (Integer key : keys) {
pukerList.add(key);
}
Collections.shuffle(pukerList);//洗牌
//创建四个ArrayList集合
ArrayList<Integer> player1 = new ArrayList<>();
ArrayList<Integer> player2 = new ArrayList<>();
ArrayList<Integer> player3 = new ArrayList<>();
ArrayList<Integer> dipai = new ArrayList<>();
for (int i = 0; i < pukerList.size(); i++) {
if (i>=pukerList.size()-3){
dipai.add(pukerList.get(i));
}else if (i%3==0){
player1.add(pukerList.get(i));
}else if (i%3==1){
player2.add(pukerList.get(i));
}else if (i%3==2){
player3.add(pukerList.get(i));
}
}
//排序
Collections.sort(dipai);
Collections.sort(player3);
Collections.sort(player2);
Collections.sort(player1);
//看牌
kanPai(pukerMap,player1,"1");
kanPai(pukerMap,player2,"2");
kanPai(pukerMap,player3,"3");
kanPai(pukerMap,dipai,"底牌");
}
//调取map里面的对应list里面的key的value
public static void kanPai(Map<Integer,String> map , ArrayList<Integer> list,String name){
System.out.print(name+":");
for (int i = 0; i < list.size(); i++) {
System.out.print(map.get(list.get(i))+" ");
}
System.out.println();
}
}