java容器集合


前言

集合

集合是提供一种存储空间可变的存储模型,其存储的数据容量可以发生改变。


集合类体系结构

在这里插入图片描述

Collection接口

Collection

1.概述
Collection是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素;
JDK 不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现。
2.使用
创建Collection集合的对象通过多态和具体的实现类。
3.常用方法
在这里插入图片描述
4.遍历
1)迭代器
Iterator iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到,所以它是依赖于集合而存在的。
常用方法:
E next( ):返回迭代中的下一个元素 ;
boolean hasNext( ) :如果迭代具有更多元素,则返回true
过程:
创建对象-添加元素-迭代器

List集合

1.概述
List集合是有序集合(序列),用户可控制列表中每个元素的插入位置,用户可以通过整数索引的位置,可搜索列表中的元素;与Set集合不同,列表通常允许重复的元素
2.特点
1)有序——存储和取出的元素顺序一致;
2)可重复——存储元素可重复;
3)有索引
3.特有方法
在这里插入图片描述
4.并发修改异常
原因:
迭代器遍历的过程中,通过集合对象修改了集合中的元素,造成了迭代器获取元素中判断预期修改值和实际修改值不一致,则会出现:ConcurrentModificationException。
解决方案:
用for循环遍历,然后用集合对象做对应的操作即可。

5.列表迭代器
概述:
列表迭代器是通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器。用于允许程序员沿任一方向遍历的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置。
好处:
使用列表迭代器添加元素时不会出现并发修改异常,因为列表迭代器在调用add方法时,将实际修改值赋值给预期修改值。

6.增强for循环
作用:简化数组和Collection集合的遍历。
概述:
实现Iterable接口的类允许其对象成为增强型for语句的目标,JDK5之后,其内部原理是一个Iterator迭代器。
格式:
for(元素数据类型 变量名 : 数组/集合对象名) {
循环体;
}

7.三种遍历——迭代器、索引for、增强for循环

8.List集合实现类
ArrayList集合:底层是数组结构实现,查询快、增删慢;
LinkedList集合:底层是链表结构实现,查询慢、增删快。

在这里插入图片描述

set集合

1.特点
1)元素存储无序;
2)没有索引,只能通过迭代器或者增强for循环遍历;
3)不能存储重复元素。

2.哈希值
1)概述
JDK根据对象的地址或字符串或数字算出来的int型数值;
2)获取方式
Object类中的public int hashCode():返回对象的哈希码值;

3.特点
1)同一个对象多次调用hashCode()方法返回的哈希值是相同的;
2)默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同。

4.HashSet集合
1)特点
底层数据结构是哈希表;
对集合的迭代顺序不保证存储和取出的元素顺序一致;
没有带索引的方法,不可普通for循环遍历;
是set集合,不包含重复元素的集合。

5.其保证元素唯一性分析
原理:
1)根据对象的哈希值计算存储位置
当前位置没有元素则直接存入;当前位置有元素存在,进入第二步。
2)当前元素和已存在元素比较哈希值
哈希值不同,则将当前元素存储;哈希值相同,进入第三步。
3)通过equals()方法比较两个元素的内容
内容不同,则存储当前元素;内容相同,则不存储当前元素。

如图所示
在这里插入图片描述
依赖于hashCodeh和equals方法

6.LinkedHashSet集合
特点:
哈希表和链表实现的Set接口,具有可预测的迭代次序;
由链表保证元素有序,也就是说元素的存储和取出顺序是一致的;
由哈希表保证元素唯一,也就是说没有重复的元素。

7.排序
TreeSet集合
特点:
元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法;
没有带索引的方法,所以不能使用普通for循环遍历;
由于是Set集合,所以不包含重复元素的集合。

自然排序Comparable的使用:
TreeSet集合存储自定义对象,无参构造方法用自然排序;
自然排序,让元素所属的类实现Comparable接口,重写compareTo(T o)方法;
重写方法时注意排序规则按照要求的主要和次要条件;

比较器排序Comparator的使用:
TreeSet集合存储自定义对象,带参构造方法用比较器排序;
比较器排序,让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法;
重写方法时注意排序规则必须按照要求的主要和次要条件;

Map集合

1.概述
interfa Map<K, V>;K: 键的类型;V:值的类型。

2.特点
1)键值映射关系
一个键对应一个值;键不能重复,值可以重复;元素存取无序
2)创建对象方式
多态;具体实现类HashMap;HashMap确定唯一值;
3)注意
如果是int类型之类的类,键和值类型要是包装类;

3.基本功能
在这里插入图片描述

4.获取功能
在这里插入图片描述
5.遍历
1)

  • 获取所有键的集合。用keySet()方法实现
  • 遍历键的集合,获取到每一个键。用增强for实现
  • 根据键去找值。用get(Object key)方法实现
    2)
  • 根据键值对对象获取键和值
  • 用getKey()得到键
  • 用getValue()得到值

泛型

1.概述
JDK5引入的特性,提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型
本质是参数化类型–所操作的数据类型被指定为一个参数。就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。
参数化类型:
泛型类、泛型方法、泛型接口

2.定义格式
<类型>:指定一种类型的格式。这里的类型可以看成是形参;
<类型1,类型2…>:指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参;
将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型;

3.优点
把运行时期的问题提前到了编译期间;
避免了强制类型转换;

4.类型通配符
1)作用:为了表示各种泛型List的父类,可以使用类型通配符;
格式:<?> 2)List<?>:表示元素类型未知的List,它的元素可以匹配任何类型;
带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中;
3)分类:
上限 <? extends 类型>; List<? extends Number>:表示的类型是Number或者其子类型;
下限 <? super Number>:表示的类型是Number或者其父类型

5.可变参数
1)概述
参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的;
2)格式
修饰符 返回值类型 方法名(数据类型…变量名){ };
3)注意
此处的变量其实是个数组;
4)使用
Arrays工具类中有一个静态方法——public static List asList(T… a):返回由指定数组支持的固定大小的列表;返回的集合不能做增删操作,可以做修改操作;
List接口中有一个静态方法——public static List of(E… elements):返回包含任意数量元素的不可变列表;返回的集合不能做增删改操作;
Set接口中有一个静态方法——public static Set of(E… elements) :返回一个包含任意数量元素的不可变集合;在给元素的时候,不能给重复的元素;返回的集合不能做增删操作,没有修改的方法;

Collections集合工具类

1.概述
此类仅由静态方法组合或者返回集合。它包含对集合进行操作的多态算法;

2.作用
是针对集合操作的工具类;

3.常用方法
在这里插入图片描述


练习

/*已知有十六支男子足球队参加2008 北京奥运会。
写一个程序,把这16支球队随机分为4个组。采用List集合和随机数
2008 北京奥运会男足参赛国家:
科特迪瓦,阿根廷,澳大利亚,塞尔维亚,荷兰,尼日利亚、日本,美国,
中国,新西 兰,巴西,比利时,韩国,喀麦隆,洪都拉斯,意大利*/
public class Test {
    public static void main(String[] args) {
        List<String> list  = new ArrayList<String>();
        list.add("科特迪瓦");
        list.add("阿根廷");
        list.add("澳大利亚");
        list.add("塞尔维亚");
        list.add("荷兰");
        list.add("尼日利亚");
        list.add("日本");
        list.add("美国");
        list.add("中国");
        list.add("新西兰");
        list.add("巴西");
        list.add("比利时");
        list.add("韩国");
        list.add("喀麦隆");
        list.add("洪都拉斯");
        list.add("意大利");
        //随机分配
        Random r = new Random();
        for(int i = 0; i < 4; i++){
            System.out.print("第"+(i+1)+"个组:");
            for(int j = 0; j < 4; j++){
                int a = r.nextInt(list.size());//随机数16
                System.out.print(list.get(a)+",");
                //避免重复
                list.remove(a);
            }
            System.out.println();
        }
    }
}
/*写一个方法reverseList,该函数能够接受一个List,然后把该List 倒序排列。 例如:
List list = new ArrayList();
list.add(“Hello”);
list.add(“World”);
list.add(“Learn”); //此时list 为Hello World Learn
reverseList(list); //调用reverseList 方法之后,list 为Learn World Hello*/
public class Test02 {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("Hello");
        list.add("World");
        list.add("Learn"); //此时list 为Hello World Learn
        reverseList(list); //调用reverseList 方法之后,list 为Learn World Hello
    }

    public static void reverseList(List list){
        for(int i = list.size(); i > 0; i--){
            System.out.println(list.get(i-1));//i-1防止索引越界
        }
    }
}
public class Test03 {
    public static void main(String[] args) {
        List list = new ArrayList();//创建集合
        //创建对象
        list.add(new Student("Tom", 18, 100, "class05"));
        list.add(new Student("Jerry", 22, 70, "class04"));
        list.add(new Student("Owen", 25, 90, "class05"));
        list.add(new Student("Jim", 30,80 , "class05"));
        list.add(new Student("Steve", 28, 66, "class06"));
        list.add(new Student("Kevin", 24, 100, "class04"));
        //平均年龄
        int sum = 0;
        //每个班级的平均分
        int g1 = 0, g2 = 0, g3 = 0;
        int c1 = 0, c2 = 0, c3 = 0;
        Iterator<Student> it = list.iterator();
        while(it.hasNext()){
            //所有学生平均年龄
            Student s = it.next();
            sum += s.getAge();
            //每个班级平均分
            if(s.getClassNum().equals("class04")){
                ++c1;
                g1 += s.getScore();
            }else if(s.getClassNum().equals("class05")){
                ++c2;
                g2 += s.getScore();
            }else{
                ++c3;
                g3 += s.getScore();
            }
        }
        System.out.println("所有学生的平均年龄为"+sum/6);
        System.out.println("班级04的平均成绩为"+g1/c1);
        System.out.println("班级05的平均成绩为"+g2/c2);
        System.out.println("班级06的平均成绩为"+g3/c3);
    }
}

class Student{
    private String name;
    private int age;
    private int score;
    private String classNum;

    public Student(){}

    public Student(String name, int age, int score, String classNum) {
        this.name = name;
        this.age = age;
        this.score = score;
        this.classNum = classNum;
    }

    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 int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public String getClassNum() {
        return classNum;
    }

    public void setClassNum(String classNum) {
        this.classNum = classNum;
    }

}
/*请将如下4个字符串数据["aaa","bbb","ccc","ddd"],
依次添加到HashSet集合中,并遍历查看存储结果。(使用增强for循环遍历)*/
public class Test {
    public static void main(String[] args) {
        //创建集合对象
        HashSet<String> s = new HashSet<>();
        //添加元素
        s.add("aaa");
        s.add("bbb");
        s.add("ccc");
        s.add("ddd");
        //增强for循环
        for(String i : s){
            System.out.println(i);
        }
    }
}
//在List集合内去除重复数字值,要求尽量简单(可借助其他集合!!)
public class Test {
    public static void main(String[] args) {
        //创建集合
        List<Integer> list = new ArrayList<>();
        //添加元素
        list.add(1);
        list.add(2);
        list.add(1);
        list.add(3);
        //利用Set集合输出不重复的数字值
        Set<Integer> set =new HashSet<>();
        set.addAll(list);
        System.out.println(set);
    }
}

/*2019年1月份的世界编程语言排行榜从高到低依次如下:
Java、C、Python、C++、Visual Basic .NET、JavaScript...
请将以上语言名称作为字符串元素,
按顺序存入set集合中,并遍历查看。要求存储和遍历的顺序保持一致。*/
public class Test {
    public static void main(String[] args) {
        //创建集合对象
        Set<String> set = new LinkedHashSet<>();
        //添加元素
        set.add("Java");
        set.add("C");
        set.add("Python");
        set.add("C++");
        set.add("Visual Basic .NET");
        set.add("JavaScript");
        //遍历
        for(String s : set){
            System.out.println(s);
        }
    }
}

//现有若干图书信息(包含名称title、作者author、定价price)需要存储到set集合中
public class Book {
    private String title;
    private String author;
    private double price;

    public  Book(){};

    public  Book(String title, String author, double price){
        this.title = title;
        this.author = author;
        this.price  = price;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Book book = (Book) o;
        return Double.compare(book.price, price) == 0 && Objects.equals(title, book.title) && Objects.equals(author, book.author);
    }

    @Override
    public int hashCode() {
        return Objects.hash(title, author, price);
    }
}

/*现有若干图书信息(包含名称title、作者author、定价price)需要存储到set集合中,
保证集合中无重复元素,并遍历查看。可以认为所有信息都相同的图书为重复数据。*/
public class Test {
    public static void main(String[] args) {
        //创建集合
        Set<Book> book = new LinkedHashSet<>();
        //创建Book对象
        Book b1 =new Book("地球往事", "小刘", 33.33);
        Book b2 =new Book("黑暗森林", "刘慈欣", 34.33);
        Book b3 =new Book("死神永生", "大刘", 35.33);
        Book b4 =new Book("黑暗森林", "刘慈欣", 34.33);
        //添加到集合
        book.add(b1);
        book.add(b2);
        book.add(b3);
        book.add(b4);
        //遍历
        for(Book boo : book){
            System.out.println(boo.getTitle()+","+boo.getAuthor()+","+boo.getPrice());
        }
    }
}

/*在某次考试中,学生的成绩信息如下(公有属性): 姓名(String) 年龄(int) 成绩(int):
Tom 20 90; Jerry 22 95; John 20 100; Lily 22 100 ;Lucy 22 90; Kevin 22 90
请分别用Comparable和Comparator两个接口对以上同学的成绩做降序排序,
如果成绩一样,那在成绩排序的基础上按照年龄由小到大排序,
成绩和年龄都一样,则按照姓名的字典顺序排序。*/
public class Student implements Comparable<Student>{
    String name;
    int age;
    int grade;

    public Student(){}

    public Student(String name, int age, int grade) {
        this.name = name;
        this.age = age;
        this.grade = grade;
    }
    //自然排序
    @Override
    public int compareTo(Student stu) {
        //主要条件
        int num = this.grade - stu.grade;
        //次要条件
        int num2 = num==0?this.age-stu.age : num;
        int num3 = num2==0?this.name.compareTo(stu.name) : num2;
        return num3;
    }
}
public class Test {
    public static void main(String[] args) {
        //创建集合,自然排序
        TreeSet<Student> stu = new TreeSet<>();

        /*//创建集合,比较器排序
        TreeSet<Student> stu = new TreeSet<Student>(new Comparator<Student>() {
            @Override
            public int compare(Student a, Student b) {
                //成绩降序
                int num = a.grade - b.grade;
                //年龄升序
                int num2 = num==0?a.age - b.age : num;
                //姓名
                int num3 = num2==0?a.name.compareTo(b.name) : num2;
                return num3;
            }
        });*/

        //创建对象
        Student s1 = new Student("Tom", 20, 90);
        Student s2 = new Student("Jerry", 22, 95);
        Student s3 = new Student("John", 20, 100);
        Student s4 = new Student("Lily", 22, 100);
        Student s5 = new Student("Lucy", 22, 90);
        Student s6 = new Student("Kevin", 22, 90);
        //添加元素
        stu.add(s1);
        stu.add(s2);
        stu.add(s3);
        stu.add(s4);
        stu.add(s5);
        stu.add(s6);
        //遍历输出
        for(Student ss : stu){
            System.out.println(ss.name+" "+ss.age+" "+ss.grade);
        }
    }
}
/*遍历Map中的key-value对,代码实现(至少2种)*/
public class Test {
    public static void main(String[] args) {
        //创建集合
        Map<String, Double> sp = new HashMap<String, Double>();
        //添加元素
        sp.put("卫生纸", 23.22);
        sp.put("冰淇淋", 3.22);
        sp.put("饮料", 5.5);
        sp.put("零食", 10.32);
        //根据键找到值
        Set<String> key = sp.keySet();
        for(String m : key ){
            Double q = sp.get(m);
            System.out.println("物品名:"+m+",价格:"+q);
        }
        System.out.println("----------------------------------");
        //键值对对象找键和值
        Set<Map.Entry<String, Double>> wp = sp.entrySet();
        for(Map.Entry<String, Double> bq : wp ){
            String name = bq.getKey();
            Double price = bq.getValue();
            System.out.println("物品名:"+name+",价格:"+price);
        }
    }
}
/*(Map)已知某学校的教学课程内容安排如下:
        前者是老师,后者是老师所教的课程:
        ("Tom", "CoreJava");
        ("John", "Oracle");
        ("Susan", "Oracle");
        ("Jerry", "JDBC");
        ("Jim", "Unix");
        ("Kevin", "JSP");
        ("Lucy", "JSP");

        完成下列要求:
        1) 使用一个Map,以老师的名字作为键,以老师教授的课程名作为值,表示上述课程安排。
        2) 增加了一位新老师Allen 教JDBC
        3) Lucy 改为教CoreJava
        4) 遍历Map,输出所有的老师及老师教授的课程(用Set<Map.Entry<String,String>>、Set<String> get(key)都可)
        5) 利用Map,输出所有教JSP的老师。*/
public class Test {
    public static void main(String[] args) {
        //创建集合
        Map<String, String> jx = new HashMap<String, String>();
        //添加元素
        jx.put("Tom", "CoreJava");
        jx.put("John", "Oracle");
        jx.put("Susan", "Oracle");
        jx.put("Jerry", "JDBC");
        jx.put("Jim", "Unix");
        jx.put("Kevin", "JSP");
        jx.put("Lucy", "JSP");
        //增加新老师Allen 教JDBC
        jx.put("Allen", "JDBC");
        //Lucy 改为教CoreJava
        jx.replace("Lucy", "JSP","CoreJava");
        //遍历Map,输出所有的老师及老师教授的课程
        Set<String> ks = jx.keySet();
        for(String name : ks){
            String course = jx.get(name);
            System.out.println(name+"老师教授"+course);
        }
        //利用Map,输出所有教JSP的老师
        for(String name : ks){
            String course = jx.get(name);
            if(course.equals("JSP")){
                System.out.println("教JSP的老师有"+name);
            }
        }
    }
}
//模拟斗地主洗牌发牌(争取根据自己的思路在写一遍)
/*
1、分析:首先应准备牌:完成数字与纸牌的映射关系:使用双列Map(HashMap)集合,完成一个数字与字符串纸牌的对应关系。

     洗牌:通过数字完成洗牌发牌(借助工具类)

     发牌:将每个人以及底牌设计,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌给3个玩家。存放的过程中要求数字大小与斗地主规则的大小对应排序。
     将代表不同纸牌的数字分配给不同的玩家与底牌。

     看牌:通过Map集合找到对应字符展示。通过查询纸牌与数字的对应关系,由数字转成纸牌字符串再进行展示。*/
public class Test {
    public static void main(String[] args) {
        //牌盒双列Map(HashMap)集合
        Map<Integer, String> po = new HashMap<Integer, String>();
        //花色和牌号数组
        String[] color = {"♦", "♣", "♥", "♠"};
        String[] num = {"3", "4","5","6","7","8","9","10","J","Q","K","A","2"};
        //添加到牌盒中
        int index = 0;
        ArrayList<Integer> number = new ArrayList<Integer>();
        for(String c : color){
            for(String n : num){
                po.put(index, c+n);
                number.add(index);
                index++;
            }
        }
        po.put(index, "小王");
        number.add(index);
        index++;
        po.put(index, "大王");
        number.add(index);
        /*Set<Map.Entry<Integer, String>> s1 = po.entrySet();
        for(Map.Entry<Integer, String> ss : s1){
            Integer key = ss.getKey();
            String value = ss.getValue();
            System.out.println(key+value);
        }*/

        //洗牌
        Collections.shuffle(number);
        //TreeSet斗地主规则牌号发牌三个人,三张底牌
        TreeSet<Integer> white = new TreeSet<>();
        TreeSet<Integer> black = new TreeSet<>();
        TreeSet<Integer> red = new TreeSet<>();
        TreeSet<Integer> dp = new TreeSet<>();

        for(int i = 0; i < number.size(); i++){
            int x = number.get(i);
            if(i >= number.size() - 3){
                dp.add(x);
            }
            else if(i%3 == 0){
                white.add(x);
            }else if(i%3 == 1){
                black.add(x);
            }else if(i%3 == 2){
                red.add(x);
            }
        }
        //看牌
        lookPoker("叶文洁", white, po);
        lookPoker("罗辑", black, po);
        lookPoker("章北海",red, po);
        lookPoker("底牌", dp, po);
    }
    public static void lookPoker(String name, TreeSet<Integer> pz, Map<Integer, String> po){
        System.out.println(name+"的牌组是");
        for(Integer i : pz){
            String poker = po.get(i);
            System.out.print(poker+" ");
        }
        System.out.println();
    }
}
/*【1】将以下车站对应关系的数据存储到map集合中,
        key:表示站编号,value:表示站名,
        并遍历打印(可以不按顺序打印):
        ------------------------------------
        站编号和站名对应关系如下:
        1 朱辛庄
        2 育知路
        3 平西府
        4 回龙观东大街
        5 霍营
        6 育新
        7 西小口
        8 永泰庄
        9 林萃桥
        10 森林公园南门
        11 奥林匹克公园
        12 奥体中心
        13 北土城
        14 安华桥
        15 安德里北街
        16 鼓楼大街
        17 什刹海
        18 南锣鼓巷
        19 中国美术馆
        ------------------------------------
        【2】计算地铁票价规则:
        总行程 3站内(包含3站)收费3元,
        3站以上但不超过5站(包含5站)的收费4元,
        5站以上的,在4元的基础上,每多1站增加2元,
        10元封顶;

        需要对键盘录入的上车站
        和到达站进行判断,如果没有该站,
        提示重新输入,直到站名存在为止
        每站需要2分钟

        示范如下:
        -------------------------------------
        请输入上车站:
        流沙河

        您输入的上车站:流沙河站不存在,请重新输入上车站:
        骑龙

        您输入的上车站:骑龙站不存在,请重新输入上车站:
        朱辛庄
        您以确定在朱辛庄上站!

        请输入到达站:
        沙河

        您输入的到达站:沙河站不存在,请重新输入到达站:
        西二旗

        您输入的到达站:西二旗站不存在,请重新输入到达站:
        西小口
        您以确定在朱辛庄下站!

        从朱辛庄到西小口共经过6站收费6元,大约需要12分钟
        -----------------------------------------------*/
public class Test {
    public static void main(String[] args) {
        //创建HashMap key:表示站编号,value:表示站名
        Map<Integer, String> subway = new HashMap<Integer, String>();
        //添加元素
        subway.put(1, "朱辛庄");
        subway.put(2, "育知路");
        subway.put(3, "平西府");
        subway.put(4, "回龙观东大街");
        subway.put(5, "霍营");
        subway.put(6, "育新");
        subway.put(7, "西小口");
        subway.put(8, "永泰庄");
        subway.put(9, "林萃桥");
        subway.put(10, "森林公园南门");
        subway.put(11, "奥林匹克公园");
        subway.put(12, "奥体中心");
        subway.put(13, "北土城");
        subway.put(14, "安华桥");
        subway.put(15, "安德里北街");
        subway.put(16, "鼓楼大街");
        subway.put(17, "什刹海");
        subway.put(18, "南锣鼓巷");
        subway.put(19, "中国美术馆");
        //遍历打印
        System.out.println("地铁路线:");
        Set<Map.Entry<Integer, String>> key = subway.entrySet();
        for (Map.Entry<Integer, String> s : key) {
            Integer b = s.getKey();
            String z = s.getValue();
            System.out.println(b + z);
        }
        String scz = null, xcz = null;
        Integer scb = 0, xcb = 0;
        //输入上车下车 没有站点 重新输入直到对为止
        System.out.println("请输入上车站:");
        boolean flag = true;
        while (flag) {
            scz = new Scanner(System.in).next();
            for (Map.Entry<Integer, String> s : key) {
                if (scz.equals(s.getValue())) {
                    scb = s.getKey();
                    System.out.println("您已确定在" + scz + "站上车");
                    flag = false;
                    break;
                }
            }
            if (flag) {
                System.out.println("您输入的上车站:" + scz + "不存在,请重新输入上车站:");
            }
        }

        System.out.println("请输入下车站:");
        boolean flag2 = true;
        while(flag2){
            xcz = new Scanner(System.in).next();
            for (Map.Entry<Integer, String> s : key){
                if(xcz.equals(s.getValue())){
                    xcb = s.getKey();
                    System.out.println("您已确定在"+xcz+"站下车");
                    System.out.println();
                    flag2 = false;
                    break;
                }
            }
            if(flag2){
                System.out.println("您输入的下车站:"+xcz+"不存在,请重新输入下车站:");
            }
        }
        //地铁票价 总行程 3站内(包含3站)收费3元,3站以上但不超过5站(包含5站)的收费4元,
        //5站以上的,在4元的基础上,每多1站增加2元,10元封顶 每站需要2分钟
        //从朱辛庄到西小口共经过6站收费6元,大约需要12分钟
        Integer stop = Math.abs(xcb - scb);
        //输出费用及时间
        int price = 0;
        if(stop == 0){
        }else if(stop < 4){
            price = 3;
        }else if(stop < 6){
            price = 4;
        }else if(stop < 9){
            price = 4+(stop-5)*2;
        }else{
            price = 10;
        }
        System.out.println("从"+scz+"到"+xcz+"共经过"+stop+"站共收费"
                    +price+"元,大约需要"+(stop*2)+"分钟");
    }
}
/*Employee 类
该类包含:private 成员变量 name,age,birthday,其中 birthday 为
MyDate 类的对象;
并为每一个属性定义 getter, setter 方法;
并重写 toString 方法输出 name, age, birthday*/
public class Employee /*implements Comparable<Employee>*/{
    private String name;
    private int age;
    private MyDate birthday;

    public Employee(String name, int age, MyDate birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    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 MyDate getBirthday() {
        return birthday;
    }

    public void setBirthday(MyDate birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return name +age + birthday ;
    }
    /*//使 Employee 实现 Comparable 接口,并按 name 排序
    @Override
    public int compareTo(Employee e) {
        int num = this.name.compareTo(e.getName());
        return num;
    }*/
}

/*MyDate 类包含:
private 成员变量 year,month,day;并为每一个属性定义 getter, setter方法;*/
public class MyDate {
    private int year;
    private int month;
    private int day;

    public MyDate(){}

    public MyDate(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    @Override
    public String toString() {
        return year + "-" + month + "-" + day;
    }
}

public class Test {
    public static void main(String[] args) {
        //泛型集合
        Set<Employee> employ = new TreeSet<>(new Comparator<Employee>() {
            @Override
            public int compare(Employee e1, Employee e2) {
                int num = e1.getBirthday().getYear() - e2.getBirthday().getYear();
                int num2 = num==0?e1.getBirthday().getMonth() - e2.getBirthday().getMonth() : num;
                int num3 = num2==0?e1.getBirthday().getDay() - e2.getBirthday().getDay() : num2;
                return num3;
            }
        });
        //创建对象并添加
        employ.add(new Employee("Tony", 55, new MyDate(1940,6,23)));
        employ.add(new Employee("Jessie", 33, new MyDate(1954,3,4)));
        employ.add(new Employee("Dany", 40, new MyDate(1960,8,14)));
        employ.add(new Employee("White", 38, new MyDate(1960,8,9)));
        employ.add(new Employee("Max", 44, new MyDate(1940,12,1)));
        //使 Employee 实现 Comparable 接口,并按 name 排序
        for(Employee e  : employ){
            System.out.println("姓名:"+e.getName()+",年龄:"+e.getAge()+",生日:"+e.getBirthday());
        }
        //按生日日期的先后排序

    }
}
/*定义个泛型类 DAO<T>,在其中定义一个 Map 成员变量,Map 的键为 String 类型,值为 T 类型。
分别创建以下方法:
public void save(String id,T entity): 保存 T 类型的对象到 Map 成员变量中
public T get(String id):从 map 中获取 id 对应的对象
public void update(String id,T entity):替换 map 中 key 为 id 的内容,改为entity对象
public List<T> list():返回 map 中存放的所有 T 对象
public void delete(String id):删除指定 id 对象
定义一个 User 类:
该类包含:private 成员变量(int 类型) id,age;(String 类型)name。
定义一个测试类:
创建 DAO 类的对象, 分别调用其 save、get、update、list、delete 方法来操作 User 对象,
创建测试类进行测试。*/


/*定义个泛型类 DAO<T>,在其中定义一个 Map 成员变量,Map 的键为 String 类型,值为 T 类型。
        分别创建以下方法:
public void save(String id,T entity): 保存 T 类型的对象到 Map 成员变量中
public T get(String id):从 map 中获取 id 对应的对象
public void update(String id,T entity):替换 map 中 key 为 id 的内容,改为entity对象
public List<T> list():返回 map 中存放的所有 T 对象
public void delete(String id):删除指定 id 对象*/
public class DAO<T>{
    Map<String, T> dx = new TreeMap<>();
    //保存 T 类型的对象到 Map 成员变量中
    public void save(String id,T entity){
        dx.put(id, entity);
    }

    //从 map 中获取 id 对应的对象
    public T get(String id){
        T entity = null;
        Set<String> key = dx.keySet();
        for(String n : key){
        if(id.equals(n)){
            entity = dx.get(n);
            }
        }
        return entity;
    }

    //替换 map 中 key 为 id 的内容,改为entity对象
    public void update(String id,T entity){
        Set<String> key = dx.keySet();
        boolean flag = true;
        for(String n : key){
            if(id.equals(n)){
                dx.replace(n, dx.get(n), entity);
                System.out.println("替换成功!");
                flag = false;
            }
        }
        if(flag){
            System.out.println("替换失败!");
        }
    }

    //返回 map 中存放的所有 T 对象
    public List<T> list(){
        List<T> list = new ArrayList<>();
        Set<String> key = dx.keySet();
        for(String k : key){
            T entity = dx.get(k);
            list.add(entity);
            System.out.println(k+dx.get(k));
        }
        return list;
    }
    //删除指定 id 对象
    public void delete(String id) {
        dx.remove(id, dx.get(id));
    }
}

//该类包含:private 成员变量(int 类型) id,age;(String 类型)name。
public class User {
    private int id;
    private int age;
    private String name;

    public User(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "编号:"+id +",年龄:"+ age +",姓名:"+ name;
    }
}

public class Test {
    public static void main(String[] args) {
        //创建DAO对象
        DAO<User> test = new DAO<>();
        //创建User对象
        User u1 = new User(1, 34, "叶文洁");
        User u2 = new User(2, 23, "罗辑");
        User u3 = new User(3, 22, "陈雪");
        User u4 = new User(4, 23, "汪淼");
        User u5 = new User(5, 16, "史强");
        User u6 = new User(6, 11, "章北海");

        //添加对象
        test.save("a",u1);
        test.save("b",u2);
        test.save("c",u3);
        test.save("d",u4);
        test.save("e",u5);
        //返回所有Map中对象
        System.out.println("添加后的对象有");
        test.list();
        //获取id对象
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入查找的id(a-e):");
        String id1 = sc.next();
        System.out.println("找到的对象为"+test.get(id1));
        //替换id的内容为新对象 b替换成f
        System.out.println("请输入被替换对象的id(a-e)");
        String id2 = sc.next();
        test.update(id2, u6);
        //删除id对象
        test.list();
        System.out.println("请输入想要删除的id(a-e)");
        String id3 = sc.next();
        test.delete(id3);
        test.list();
    }
}
/*开发一个泛型Apple类,要求有一个重量属性weight
在测试类中实例化不同的泛型对象,
要求
对象a1的这一属性是String类型,
对象a2的这一属性是Integer型,
对象a3的这一属性是Double型。
分别为a1,a2,a3的重量属性赋值为:”500克”,500,500.0,
在测试类中通过对象调用访问器得到属性值并输出。
另外思考,为什么a2和a3的属性需要是Integer和Double而不是int和double?
答:具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型*/

//开发一个泛型Apple类,要求有一个重量属性weight
public class Apple <T>{
    private T weight;

    public Apple(){};

    public Apple(T weight) {
        this.weight = weight;
    }

    public T getWeight() {
        return weight;
    }

    public void setWeight(T weight) {
        this.weight = weight;
    }
}

public class Test {
    public static void main(String[] args) {
        //实例化对象
        Apple a = new Apple();
        Apple b = new Apple();
        Apple c = new Apple();
        //赋值
        a.setWeight("500克");
        b.setWeight(500);
        c.setWeight(500.0);
        //输出
        System.out.println("对象1 "+a.getWeight());
        System.out.println("对象2 "+b.getWeight());
        System.out.println("对象3 "+c.getWeight());
    }
}
/*按要求完成下列任务
(1.使用HashMap类实例化一个Map类型的对象m1,键(String类型)和值(int型)分别用于存储员工的姓名和工资,
存入数据如下:	张三——800元;李四——1500元;王五——3000元;
(2.将张三的工资更改为2600元
(3.为所有员工工资加薪100元;
(4.遍历集合中所有的员工
(5.遍历集合中所有的工资*/

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        //实例化
        Map<String, Integer> m1 = new HashMap<>();
        //存入数据
        m1.put("张三", 800);
        m1.put("李四", 1500);
        m1.put("王五", 3000);
        //将张三的工资更改为2600元
        m1.replace("张三", 800,2600);
        //为所有员工工资加薪100元
        Set<String> key = m1.keySet();
        for(String k : key){
            Integer wage = m1.get(k);
            System.out.println(k+", "+(wage+100));
            System.out.println("------------------");
        }
    }
}
/*
(Map)利用Map,完成下面的功能:
从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队。如果该年没有举办世界杯,则输出:没有举办世界杯。
附:世界杯冠军以及对应的夺冠年份,请参考本章附录。 附录
1.	历届世界杯冠军
届数	举办年份	举办地点	冠军
第一届	1930年	乌拉圭	乌拉圭
第二届	1934年	意大利	意大利
第三届	1938年	法国	意大利
第四届	1950年	巴西	乌拉圭
第五届	1954年	瑞士	西德
第六届	1958年	瑞典	巴西
第七届	1962年	智利	巴西
第八届	1966年	英格兰	英格兰
第九届	1970年	墨西哥	巴西
第十届	1974年	前西德	西德
第十一届	1978年	阿根廷	阿根廷
第十二届	1982年	西班牙	意大利
第十三届	1986年	墨西哥	阿根廷
第十四届	1990年	意大利	西德
第十五届	1994年	美国	巴西
第十六届	1998年	法国	法国
第十七届	2002年	韩日	巴西
第十八届	2006年	德国	意大利
第十九届	2010年	南非	西班牙
第二十届	2014年	巴西	德国
(Map)在原有世界杯Map 的基础上,增加如下功能: 读入一支球队的名字,输出该球队夺冠的年份列表。
例如,读入“巴西”,应当输出 1958 1962 1970 1994 2002 读入“荷兰”,应当输出 没有获得过世界杯
*/

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        //创建集合
        Map<String, String> worldCup = new HashMap<>();
        //输入年份 判断球队
        worldCup.put("1930", "乌拉圭");worldCup.put("1934", "意大利");
        worldCup.put("1938", "意大利");worldCup.put("1950", "乌拉圭");
        worldCup.put("1954", "西德");worldCup.put("1958", "巴西");
        worldCup.put("1962", "巴西");worldCup.put("1966", "英格兰");
        worldCup.put("1970", "巴西");worldCup.put("1974", "西德");
        worldCup.put("1978", "阿根廷");worldCup.put("1982", "意大利");
        worldCup.put("1986", "阿根廷");worldCup.put("1990", "西德");
        worldCup.put("1994", "巴西");worldCup.put("1998", "法国");
        worldCup.put("2002", "巴西");worldCup.put("2006", "意大利");
        worldCup.put("2010", "西班牙");worldCup.put("2018", "德国");
        //输入年份显示对应冠军
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入想要查询世界杯的年份:");
        String year = sc.next();
        Set<String> key = worldCup.keySet();
        boolean flag = true;
        for(String y : key ){
            if(y.equals(year)){
                String champ = worldCup.get(y);
                System.out.println("该年的世界杯冠军是"+champ+"球队");
                flag = false;
            }
        }
        if(flag){
            System.out.println("该年没有举办世界杯!");
        }
        //输入球队输出夺冠年份
        System.out.println("请输入想要查询的球队:");
        String team = sc.next();
        boolean flag2 = true;
        for(String y : key){
            if(worldCup.get(y).equals(team)){
                System.out.print(y+" ");
                flag2 = false;
            }
        }
        if(flag2){
            System.out.println(team+"没有获得过世界杯");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值