集合框架2

  • 今日目标
    • 一.泛型
      • 1.泛型类
      • 2.泛型接口
      • 3.泛型方法
      • 4.泛型通配符
    • 二.集合工具类
    • 三.TreeMap和TreeSet
      • 作业:

今日目标

  • 泛型
  • 集合工具类
  • 自带排序集合

一.泛型

​ Java泛型是jdk 1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

  • 引入案例

    需求:输出集合中所有的字符串

ArrayList list = new ArrayList();
list.add("hello");
list.add("world");
list.add(666);
//需求:输出集合中所以的字符串
for (Object o:list){//会抛出类型转换异常System.out.println((String)o);
}
//异常分析:集合中数据类型不统一
  • 案例改进

    在源头上对数据进行约束,除了字符串,其它类型数据不能放入集合

//增加了泛型对类型进行约束
ArrayList <String>list = new ArrayList();
list.add("hello");
list.add("world");
list.add(666);//编译不通过
for (String s:list){//直接用String接收,无须强转//会抛出类型转换异常System.out.println(s);
}

1.泛型类

​ 类的后面定义一个或多个任意类型 ,可以在类的成员属性或方法中使用,例如:

public class Hello<T,A,B,C> {// <> 里表示声明private T t;private A a;private B b;private C c;//省略seter/getter和构造方法//应用于方法的形参public void fun1(A a){System.out.println(a);}public void fun2(B b){System.out.println(b);}public void fun3(C c){System.out.println(b);}
}
//测试类中,调用构造方法,传入不同的类型作为参数,创建对象。
  • 常见应用:List,Set,Map接口

案例:

  1. 定义一个Set集合,装入5本书(编号,书名,价格),且只能装入书籍。
  2. 定义一个Map集合,用来存入人物名称和对应的城池(刘备-荆州,张飞-徐州,关羽-樊城),使用泛型约束类型。
public class City {private String city;@Overridepublic String toString() {return "City{" +"city='" + city + '\'' +'}';}public City() {}public City(String city) {this.city = city;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}
}
import javax.print.attribute.standard.Chromaticity;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class Fx {public static void main(String[] args) {HashMap<String, City> map = new HashMap();map.put("关羽",new City("樊城"));map.put("张飞",new City("新野"));map.put("赵子龙",new City("徐州"));map.put("刘备",new City("荆州"));Set<String> keys = map.keySet();for (String s:keys){System.out.println(s+"---"+map.get(s));}Collection<City> values = map.values();for (City c:values){System.out.println(c);}Set<Map.Entry<String, City>> entries = map.entrySet();for (Map.Entry<String, City> entry:entries){System.out.println(entry.getKey()+"----"+entry.getValue());}}
}

  1. 定义一个人类People,声明3个泛型,尝试着从不同的方面去描述不同的人物,创建不同的对象。
 People<String , Double, Integer> people1 = new  People<>("曹操",999.99,26);People<String , Boolean, Character> people2 = new  People<>("刘备",false,'男');

public class People <A,B,C>{private A a;private B b;private C c;public People(A a, B b, C c) {this.a = a;this.b = b;this.c = c;}
}
public class TestPeople {public static void main(String[] args) {People p1 = new People<String, Double, Integer>("曹操", 999.99, 26);People p2 = new People<String, Boolean, Character>("刘备", false, '男');People <Boolean,Double,Character>p3 = new People("刘备", false, '男');//如果有类被指定,构造方法无需指定,若要指定要与类一致//People <Boolean,Double,Character>p3 = new People<String, Boolean, Character>("刘备", false, '男');People <String, Boolean, Character>p4 = new People<String, Boolean, Character>("刘备", false, '男');}
}

2.泛型接口

public interface Haha <T> {void ff(T t);
}
  • 编写实现类,重写ff方法

  • 常见应用:比较器Comparable

3.泛型方法

​ 在方法结构上声明一个或多个泛型,可用于方法的返回值或形参。

 public <T> void fun1(T t){System.out.println(t);}public <T> T fun1(T t){System.out.println(t);return t;}

4.泛型通配符

​ <? extends 类型> 表示某个类型或它的任意子类型

​ <? super 类型> 表示某个类型或它的任意父类型

案例

​ 动物类Animal有一个方法,返回动物的腿的个数。子类有狗狗和企鹅,分别重写该方法,返回各自腿的个数。

编写一个测试类,定义一个方法,该方法可以计算出一个动物集合List共有多少条腿,并输出。

再定义一个测试方法,分别计算一批动物(2只狗狗和3只企鹅)和一批狗狗(3只),一批企鹅(3只)的腿的数量。

public abstract class Animal {abstract int legs();
}
class Dog extends Animal{@Overrideint legs() {return 4;}
}
class Penguin extends Animal{@Overrideint legs() {return 2;}
}
class TestAni{static void calLegs(List<? extends Animal> animals){// List集合中可以是<? extends Animal> 这些类 也可用ArrayList<? extends Animal> animalsint sum=0;for(Animal a:animals){sum+=a.legs();}System.out.println("这批动物的腿的个数:"+sum);}public static void main(String[] args) {//准备第一批:2只狗狗和3只企鹅ArrayList<Animal> animals = new ArrayList<>();animals.add(new Dog());animals.add(new Dog());animals.add(new Penguin());animals.add(new Penguin());animals.add(new Penguin());calLegs(animals);//准备第二批:3只狗狗ArrayList<Dog> animals2 = new ArrayList<>();animals2.add(new Dog());animals2.add(new Dog());animals2.add(new Dog());calLegs(animals2);//准备第三批:3只企鹅ArrayList<Penguin> animals3 = new ArrayList<>();animals3.add(new Penguin());animals3.add(new Penguin());animals3.add(new Penguin());calLegs(animals3);}
}

二.集合工具类

Collections工具类:是一个主要对List集合进行操作的工具类,里面包含静态方法。

  • 随机打乱shuffle
  • 排序sort
  • 交换swap
  • 查找binarySearch:前提是集合中的元素必须按某种规则升序排序
 public static void main(String[] args) {ArrayList list = new ArrayList();list.add(1);list.add(2);list.add(3);list.add(4);Collections.shuffle(list);System.out.println(list);Collections.sort(list);System.out.println(list);System.out.println(Collections.binarySearch(list,4));Collections.swap(list,1,2);System.out.println(list);}

public static void main(String[] args) {Integer [] arr={1,2,3};List<Integer> l = Arrays.asList(arr);//将数组转换为集合System.out.println(l);System.out.println(l.size());System.out.println("-------");int [] arr1={1,2,3};IntStream s = Arrays.stream(arr1);//遍历流s.forEach(System.out::println);/* Stream<Integer> ss = s.boxed();List<Integer> list = ss.collect(Collectors.toList());*//*IntStream s = Arrays.stream(arr);s.forEach(System.out::println);
List<Integer> list = Arrays.stream(arr1).boxed().collect(Collectors.toList());System.out.println(list);System.out.println(list.size());*/}

案例:

1.现有5只猴子(姓名,年龄),将他们存入List集合中,先随机打乱,然后使用工具类,对这一群猴子按照年龄进行排序。

2.交换集合中的第一个和第三个猴子

3.查找名称叫 肉肉 的猴子

public class Monkey implements Comparable<Monkey>{@Overridepublic int compareTo(Monkey o) {return this.age-o.age;//return this.name.compareTo(o.name);}private String name;private int age;@Overridepublic String toString() {return "Monkey{" +"name='" + name + '\'' +", age=" + age +'}';}public Monkey(String name, int age) {this.name = name;this.age = age;}public Monkey() {}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;}
}
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestM {public static void main(String[] args) {Monkey[] monkeys={new Monkey("孙悟空",6),new Monkey("菲菲",1),new Monkey("肥肥",6),new Monkey("狒狒",2),new Monkey("肉肉",9)};List<Monkey> ms = Arrays.asList(monkeys);//随机打乱Collections.shuffle(ms);System.out.println(ms);//内部比较器,实体类实现Comparable接口Collections.sort(ms);System.out.println(ms);//再次随机打乱/* Collections.shuffle(ms);System.out.println(ms);*///外部比较器 如下2种方式都行//Collections.sort(ms,new AgeCompare());/*Collections.sort(ms,( o1, o2)-> o1.getAge()-o2.getAge());System.out.println(ms);*///查找 肉肉  查找什么属性,就要按照什么属性排序//内部比较器 查找int i = Collections.binarySearch(ms, new Monkey("肉肉", 2));System.out.println(i);//外部比较器查找//int i1 = Collections.binarySearch(ms, new Monkey("肉肉", 1), new NameCompare());/*int i2 = Collections.binarySearch(ms,new Monkey("肉肉", 1), (o1,o2)->o1.getName().compareTo(o2.getName()));System.out.println(i2);*/}
}
class NameCompare implements Comparator<Monkey> {@Overridepublic int compare(Monkey o1, Monkey o2) {return o1.getName().compareTo(o2.getName());}
}
class AgeCompare implements Comparator<Monkey> {@Overridepublic int compare(Monkey o1, Monkey o2) {return o1.getAge()-o2.getAge();}
}

三.TreeMap和TreeSet

  1. Set和Map的关系:

    set使用了map的key.

  2. 继承关系:

    Set接口有一个实现类是HashSet,还有一个子接口是SortedSet,该接口有一个实现类是TreeSet。

TreeSet是一个有序集合,会根据自然排序排列或比较器进行排序,且没有重复元素,也没有下标。通过TreeMap实现。

TreeMap中的元素默认按照keys的自然排序排列或比较器进行排序。

  • 构造方法
//1.无参构造
new TreeSet<>();
new TreeMap<>();
//2.有参构造
new TreeSet<>(外部比较器Comparator);
new TreeMap<>(外部比较器Comparator);

案例:

1.将5个大象(姓名,年龄,体重)存入TreeSet中,并输出

public class Elephant implements Comparable<Elephant>{@Overridepublic int compareTo(Elephant o) {return this.age-o.age;}private String name;private int age;private double weight;@Overridepublic String toString() {return "Elephant{" +"name='" + name + '\'' +", age=" + age +", weight=" + weight +'}';}public Elephant() {}public Elephant(String name, int age, double weight) {this.name = name;this.age = age;this.weight = weight;}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 double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}
}
public class TestTreeSet {/*1.将5个大象(姓名,年龄,体重)存入TreeSet中,并输出* 2.给每一个大象安排一个主人,存入TreeMap中,并输出*/public static void main(String[] args) {fun1();}private static void fun2() {TreeMap<String,Elephant> es = new TreeMap<String,Elephant>();es.put("曹操",new Elephant("胖胖",2,3.6));es.put("曹植",new Elephant("肥肥",1,4.6));es.put("曹丕",new Elephant("菲菲",3,5.6));es.put("曹洪",new Elephant("毛毛",8,2.6));es.put("曹仁",new Elephant("壮壮",5,1.6));System.out.println(es);}private static void fun1() {//自然排序--基本数据类型/* TreeSet<Integer> es = new TreeSet();es.add(2);es.add(6);es.add(9);es.add(0);*//* //内部比较器排序--对象TreeSet<Elephant> es = new TreeSet();es.add(new Elephant("胖胖",2,3.6));es.add(new Elephant("肥肥",1,4.6));es.add(new Elephant("菲菲",3,5.6));es.add(new Elephant("毛毛",8,2.6));es.add(new Elephant("壮壮",5,1.6));System.out.println(es);*///外部比较器排序--对象TreeSet<Elephant> es = new TreeSet<Elephant>((o1, o2)-> Double.compare(o1.getWeight(),o2.getWeight()) );es.add(new Elephant("胖胖",2,3.6));es.add(new Elephant("肥肥",1,4.6));es.add(new Elephant("菲菲",3,5.6));es.add(new Elephant("毛毛",8,2.6));es.add(new Elephant("壮壮",5,1.6));System.out.println(es);}
}

2.给每一个大象安排一个主人,存入TreeMap中,并输出

public class Elephant {private String name;private int age;private double weight;@Overridepublic String toString() {return "Elephant{" +"name='" + name + '\'' +", age=" + age +", weight=" + weight +'}'+"\n";}public Elephant() {}public Elephant(String name, int age, double weight) {this.name = name;this.age = age;this.weight = weight;}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 double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}
}
public static void main(String[] args) {TreeMap<String, Elephant> treeMap = new TreeMap<>();treeMap.put("曹操3",new Elephant("大1",2,3.6));treeMap.put("曹操2",new Elephant("大3",5,2.6));treeMap.put("曹操5",new Elephant("大5",1,4.6));treeMap.put("曹操6",new Elephant("大2",3,1.6));treeMap.put("曹操1",new Elephant("大6",4,6.6));System.out.println(treeMap);}

作业:

1.判断以下哪种书写时正确的?


1.4.5正确

2.将一系列字符串“hello”,“helloworld”,“how”,“do”,“you”,"what"存入TreeSet集合,要求按照字符串长度进行排序。

import java.util.Comparator;
import java.util.TreeSet;public class Test {public static void main(String[] args) {TreeSet<String> set = new TreeSet<>(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {if (o1.length()!=o2.length()){return o1.length()-o2.length();
}else {return 1;
}}});set.add("hello");set.add("helloworld");set.add("how");set.add("do");set.add("you");set.add("what");System.out.println(set);}
}

3.有一个记事本,可以记录做了哪些事情和每件事对应得次数。请输入10件事,可以重复,例如:

学java,

打球,

溜冰,

打球,

溜冰,

打球,

打球,

学java,

溜冰,

吃烧烤。

输入结束后,输出每件事和对应得次数,例如:

学java–2次

打球–4次

溜冰–3次

吃烧烤–1次

要求:所选的集合都要用泛型进行约束。

 HashMap<String, Integer> map = new HashMap<>();Scanner sc = new Scanner(System.in);for (int i = 1; i <=10 ; i++) {System.out.println("请输入第"+i+"件事");String s=sc.next();map.put(s,map.containsKey(s)?map.get(s)+1:1);}Set<Map.Entry<String, Integer>> entries = map.entrySet();for (Map.Entry<String, Integer> entry:entries){System.out.println(entry.getKey()+"的次数有"+entry.getValue());}

集合嵌套应用–选做:

4.有一个记事本,能记录周一到周天,每天做的所有事情和事情的次数,周而复始。小明在这个记事本上记录了3周,内容如下:

第1周

  • 周1:学java,逛街
  • 周2:打台球,旅游
  • 周3:溜冰,吃烧烤
  • 周4:打篮球,逛街,吃烧烤
  • 周5:学前端,溜冰
  • 周6:逛街,吃烧烤
  • 周7:旅游,打台球

第2周:

  • 周1:学java,学前端
  • 周2:打台球,溜冰,学java
  • 周3:旅游,吃烧烤
  • 周4:逛街,学java
  • 周5:学前端,旅游
  • 周6:逛街,打台球,吃烧烤
  • 周7:旅游,逛街,打台球,吃烧烤

第3周:

  • 周1:学java,学前端,学python
  • 周2:打台球,溜冰,学java,学C++
  • 周3:旅游,吃烧烤,吃冰淇淋
  • 周4:逛街,学java,吃烧烤
  • 周5:学前端,旅游,打高尔夫
  • 周6:逛街,打台球,吃烧烤,溜冰,蹦迪
  • 周7:旅游,逛街,打台球,吃烧烤,跑步

使用Scanner接收小明3周所做的所有事情,并存入相应的集合中。然后输出周一到周五(不区分第几周)小明所做的所有事情以及相应的次数。(要求:所选的集合都要用泛型进行约束。)

public static void main(String [] args){Scanner sc=new Scanner(System.in);//week 共有7个元素TreeMap<String, Map<String,Integer>> week = new TreeMap<String, Map<String,Integer>>();//数据录入for (int i = 1; i <= 2; i++) {System.out.println("第"+i+"周:");Map<String, Integer> map;for (int j = 1; j <=3 ; j++) {map= new HashMap<String, Integer>();//每天都会清空昨天的事情和次数System.out.println("周"+j+":");String things = sc.next();//旅游,逛街,旅游,打台球,吃烧烤,跑步String[] things_arr = things.split(",");for (String s : things_arr) {//map存入的是:事情和次数map.put(s,map.containsKey(s)?map.get(s)+1:1);}//第二周,第三周if(week.containsKey("周"+j)){Map<String, Integer> map1 = week.get("周" + j);mapAddMap(map1,map);//week.put("周"+j,map);}else {//第一周week.put("周"+j,map);}}}//数据输出 weekSet<Map.Entry<String, Map<String, Integer>>> weeks = week.entrySet();for (Map.Entry<String, Map<String, Integer>> week1 : weeks) {System.out.println(week1.getKey()+":");Map<String, Integer> map = week1.getValue();Set<Map.Entry<String, Integer>> things = map.entrySet();for (Map.Entry<String, Integer> thing : things) {String key = thing.getKey();Integer count = thing.getValue();System.out.print(key+"--"+count+"次 \t");}System.out.println();//换行}}public static void mapAddMap(Map<String ,Integer> map1,Map<String ,Integer> map2){Set<String> map2key = map2.keySet();for (String m2key : map2key) {map1.put(m2key,map1.containsKey(m2key)?map1.get(m2key)+map2.get(m2key):map2.get(m2key));}}

Java学习顺序

Java学习day18-集合框架2(泛型,工具类,TreeMap)相关推荐

  1. Java学习---day14_集合框架03

    Java学习-day14_集合框架03 Set集合 Set集合中,没有下标的概念 Set集合,是一个去重复的集合.在Set集合中不会添加重复的元素的 在向一个Set集合中添加元素的时候,会先判断这个元 ...

  2. 黑马程序员java学习日记——集合框架

    ------- android培训.java培训.期待与您交流! ---------- Java.util包中提供了一些集合类,这些集合类又被称为容器.集合类与数组的不同之处是,数组长度是固定的,集合 ...

  3. Java集合框架:Collections工具类

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  4. java学习日记 集合框架

    集合框架 有两大接口  一个是 Collection (类集 )与Map (映射): collection 下有两大接口  一个是List (列表) 另一个是Set(集合) List (列表):Arr ...

  5. 【java学习】集合框架

    1,常用map AbstractMap 的成员变量:transient, volatile修饰 transient volatile Set<K> keySet;//keySet, 保存 ...

  6. Java集合框架:Arrays工具类

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  7. Java学习关于集合框架的基础接口--Collection接口

     集合框架(Collection  Framework)是Java最强大的子系统之一,位于java.util 包中.集合框架是一个复杂的接口与和类层次,提供了管理对象组的最新技术.Java集合框架标准 ...

  8. 【Java高级特性】集合框架和泛型(一)

    1.认识集合 Java中可以使用数组存储多个类型相同的数据,但是使用数组存在如下缺陷: 数组长度固定,不能很好的适应元素动态变化的情况: 可以通过数组名.length获取数组的长度,但是不能直接获取数 ...

  9. java中的集合框架_JAVA中的集合框架(上)List

    第一节 JAVA中的集合框架概述 集合的概念,现实生活中:很多事物凑在一起就是一个集合:数学中的集合:具有相同属性事物的总体:JAVA中的集合:是一种工具类,就像是容器,储存任意数量的具有共同属性的对 ...

最新文章

  1. 在机器学习中处理大量数据!
  2. iOS 9: UIStackView入门
  3. DOM编程中,提高程序运行速度需要注意的一些点
  4. 14.并发与异步 - 2.任务Task -《果壳中的c#》
  5. 阿里云盘小白羊版 v2.9.19 绿色版
  6. cmake安装更新(解决cmake报错:CMake 3.8 or higher is required. You are running version 3.5.1
  7. 第三章 寄存器(内存访问)
  8. 桌面应用程序 azure_如何在Azure中连接我们的C#应用​​程序
  9. 【机房收费系统】---结账
  10. mysql 记录更新时间_MySQL表内更新时,自动记录时间
  11. Sandcastle Help File Builder(.NET帮助文档工具)的版本选择心得——支持VS2010至VS2015,高版本项目文件问题...
  12. iCartoonFace:爱奇艺的动漫人脸数据集
  13. 单片机中的冒泡排序(汇编语言)
  14. ffmpeg 将视频转换为图片
  15. 使用 Sublime 比较文档差异
  16. 蒟蒻的做题录(时间)
  17. Java设计模式实战 ~ 观察者模式分析与实战
  18. 【重要公告】包头市新型冠状病毒感染肺炎防控工作指挥部公告(2022年第4、5、6、7号)
  19. 【阿里云高校计划】在线Linux学习
  20. 【KALI使用】12搜索引擎Google、YANDEX、Maltego

热门文章

  1. (短信服务)java SpringBoot 阿里云短信功能实现发送手机验证码
  2. Java 字符串 之 字符串拆分
  3. Tushare所有版块数据获取(python)
  4. 【php】empty()详解
  5. ret和retf的区别和用法
  6. PD充电加数据OTG方案
  7. 透明表——ABAP程序创建透明表
  8. MAC下搭建Hexo博客
  9. FastDFS,Redis,Solr,ActiveMQ核心技术整合二(1)
  10. Oracle服务器和客户端的安装(图解)