Java基础_17TreeSet和内部类和Map集合

回顾
1.LinkedList
	双向链表
2.Object类
	1.toString方法
	2.equals方法
	3.hashCode方法
2.Set集合
	HashSet
		
	TreeSet
	

今天的内容

1.TreeSet

2.内部类

3.Map集合

1.TreeSet

Set 接口下面的一个实现类

底层是二叉树

存储的数据的时候不可重复的。可以进行自然排序的!!!

package com.qf.a_treeset;

import java.util.Set;
import java.util.TreeSet;

public class Demo1 {
    public static void main(String[] args) {
        Set<Integer> set = new TreeSet<>();
        set.add(23);
        set.add(12);
        set.add(17);
        set.add(78);
        set.add(2);
        set.add(23);
        System.out.println(set);


        Set<String> set1 = new TreeSet<>();
        set1.add("d");
        set1.add("c");
        set1.add("a");
        set1.add("b");
        set1.add("d");
        //[a, b, c, d]
        System.out.println(set1);

    }
}

1.1TreeSet 存 自定义的类对象

刚才讲的是Integer和String类型存到TreeSet 没有报错,但是进行排序。在比较。

这两个实现了一个接口叫Comparable接口,给类强加了整体的排序功能

所以想要将Person类对象存到TreeSet要进行排序,在比较。实现Comparable接口

int	compareTo(T o)
将此对象与指定的对象进行比较以进行排序。

返回一个负整数,零或正整数,因为该对象小于,等于或大于指定对象。

person1.compareTo(person2); 有返回值的

返回值是负数: person1小于person2 person1排在person2的前面

返回值是0: person1等于person2 person1,person2只保留一个

返回值是正数: person1大于person2 person2 在person1前面

package com.qf.a_treeset;

import java.util.Set;
import java.util.TreeSet;

class Person implements Comparable<Person>{
    String name;
    int age;

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Person o) {
        //按照Person对象的属性 age 进行排序
        int num = this.age - o.age;
        return num;
    }
}
public class Demo2 {
    public static void main(String[] args) {
        Set<Person> set = new TreeSet<>();
        //java.lang.ClassCastException:
        // com.qf.a_treeset.Person cannot be cast to java.lang.Comparable
        //	at java.util.TreeMap.compare(TreeMap.java:1294)
        //Person类无法转换成Comparable
        //Person类不具备排序的功能!!!
        //该接口对实现它的每个类的对象强加一个整体排序。
        // 这个排序被称为类的自然排序
        //让Person类实现Comparable接口,强加一个整体排序

        set.add(new Person("骚磊", 34));
        set.add(new Person("老邢", 23));
        set.add(new Person("老万", 23));
        set.add(new Person("瑞哥", 32));
        System.out.println(set);

    }
}

执行流程:
	第一次:进入到了CompraTo方法
		this:  骚磊 34
		o: 骚磊 34
	第二次:进入到了CompraTo方法
		this:  老邢 23
		o: 骚磊 34
		
		num= -11  [老邢  骚磊]
	第三次:进入到了CompraTo方法
		this:  老万 23
		o: 骚磊 34
		
		num= -11  [ 老万 骚磊]
		
	第四次:进入到了CompraTo方法
		this:  老万 23
		o: 老邢 23
		
		num= 0  [ 老邢 骚磊]
	第五次:进入到了CompraTo方法
		this:  瑞哥 32
		o: 骚磊 34
		num=-2  [瑞哥  骚磊]
	第六次进入到了CompraTo方法
		this:  瑞哥 32
		o: 老邢 23
		num=9  [老邢 瑞哥  骚磊]

扩展

二叉树
1、TeeSet/TreeMap是自平衡二叉树(AVL),遵循左小右大原则存放

      存放是要依靠左小右大原则,存放时,要进行比较

2、遍历二叉树三种方式

(1)前序遍历:根左右

(2)中序遍历:左根右

(3)后序遍历:左右根

注:

前中后说的是“根” 的位置

根在前面是前序;根在中间是中序;根在后面是后序

3、 TreeSet集合/TreeMap集合采用的是:中序遍历方式(左根右)

Iterator迭代器采用的是中序遍历方式

存放的过程就是排序的过程,取出来就是自动按照大小顺序排列的

如下数据:

5        2        8        1        4        7        9        3

在二叉树中表示如下:



进行中序遍历方式(左跟右) 遍历取出,会得到

1        2        3        4        5(根)        7        8        9

如果想深入的研究二叉树数据结构可查阅数据结构相关书籍

案例:

使用TreeSet存Employee,两个属性。String name int age

要求先按照年龄进行排序升序。如果年龄一样,则按照字符串的字典的自然顺序排。

package com.qf.a_treeset;

import java.util.Set;
import java.util.TreeSet;
class Employee implements Comparable<Employee> {
    String name;
    int age;

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

    @Override
    public int compareTo(Employee o) {
        //先按照年龄排,年龄一样再按照名字字典顺序排
        int num = this.age - o.age;
        if (num == 0) {//年龄相等的
            //比较字符串
            //ublic int compareTo(String anotherString)
            //按字典顺序比较两个字符串。 比较是基于字符串中每个字符的Unicode值。
            int num1 = this.name.compareTo(o.name);
            return num1;
        }


        return num;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Demo3 {
    public static void main(String[] args) {
//        String str1 = "中";
//        String str2 = "国";
//        System.out.println(str1.compareTo(str2));//0
        Set<Employee> set = new TreeSet<>();
        set.add(new Employee("b", 23));
        set.add(new Employee("a", 13));
        set.add(new Employee("d", 23));
        set.add(new Employee("a", 23));
        set.add(new Employee("e", 12));
        System.out.println(set);
        //e   c   a  b  d
    }
}

总结:

Collection 集合
	ArrayList:    开发用的最多 底层是数组
		不用管那么多,直接对象调用方法即可
	LinkedList:   底层是链表
		不用管那么多,直接对象调用方法即可
	HashSet:   底层是依靠hash值进行存储
		重写equals和hahsCode方法
	TreeSet:    底层是二叉树
		实现Comparable这个接口,重写抽象方法 compareTo方法

发现咱们通过Comparable这个接口实现排序

还有一种排序接口Comparator叫比较器

TreeSet(Comparator<? super E> comparator)

构造一个新的,空的树集,根据指定的比较器进行排序。

package com.qf.a_treeset;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
class People {
    String name;
    int age;

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

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
class MyComparator implements Comparator<People> {

    @Override
    public int compare(People o1, People o2) {
        int num1 = o1.age - o2.age;
        return num1;
    }
}
public class Demo4 {
    public static void main(String[] args) {

        Set<People> set1 = new TreeSet<>(new MyComparator());
        set1.add(new People("狗蛋", 12));
        set1.add(new People("狗蛋1", 1));
        set1.add(new People("狗蛋2", 2));
        set1.add(new People("狗蛋3", 22));
        System.out.println(set1);
    }
}

回顾

1.TreeSet 存数据  不可重复的  进行自然排序的
	Integer
	String
2.TreeSet 存自定义的对象
	1.实现一个接口  Comparable这个接口
	2.重写int  compareTo(T o1)方法
	根据某一个属性排序进行存储
	
3.一个接口Comparetor  比较器
	1.用一个类去实现Comparetor 接口
	2.重写一个方法 int compare(T o1, T o2);

2.内部类

1.成员内部类【了解】

2.静态内部类【了解】

3.匿名内部类【要用】

2.1成员内部类
package com.qf.b_inner;

class Outer {
    //成员变量
     int age = 18;
     String name = "张三";
    //成员方法
    public  void test () {
        //在外部类中取访问内部类的属性
        Inner inner = new Inner();
        System.out.println("======"+inner.age);
        System.out.println("outer的方法test" );
    }
    //成员内部类
    class Inner {
        int age = 19;
         String name = "李四";
        public void test () {
            //在内部类中去调用外部类中的属性
            System.out.println("----------"+Outer.this.name);
            System.out.println("inner的方法test" );
        }
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Outer outer = new Outer();
        System.out.println(outer.name);
        System.out.println(outer.age);
        outer.test();
        //使用内部类
        //外部类.内部类   内部类的对象 = new 外部类().new 内部类();
        Outer.Inner inner = new Outer().new Inner();
        System.out.println(inner.name);
        System.out.println(inner.age);
        inner.test();

    }
}

2.2静态内部类
package com.qf.b_inner;

class Outer1 {
    static int age = 12;
    String name = "狗蛋";

    //静态内部类
    static class Inner1 {
        //int age = 89;
        public void test () {
            //静态类对象不需要外部类的对象
            System.out.println(age);
        }
    }
}
public class Demo2 {
    public static void main(String[] args) {
        Outer1.Inner1 inner1 = new Outer1.Inner1();
        inner1.test();
    }
}
2.3匿名内部类

现在用接口的话咋办? 用一个类去实现这个接口重写方法。实例化这个类即可

现在呢? 咱们使用匿名内部类。

package com.qf.b_inner;


interface A {
    void fun();
}
public class Demo3 {
    public static void main(String[] args) {
        A a = new A(){
            @Override
            public void fun() {
                System.out.println("嘻嘻 玩吧");
            }
        };
        a.fun();
        System.out.println("=========");
        //不用在用一个类去实现接口了,直接new接口,但是实现接口的抽象的方法
        new A() {
            @Override
            public void fun() {
                System.out.println("哈哈看鬼片吧");
            }
        }.fun();

    }
}

开发中的用法

当一个方法的参数(形参)是一个接口的时候,直接在这个方法中 new 接口即可

package com.qf.b_inner;

interface B {
    void test();
}

public class Demo4 {
    public static void main(String[] args) {
        xixi(new B() {
            @Override
            public void test() {
                System.out.println("你是测试的");
            }
        });
    }
    public static void xixi(B b) {
        b.test();
    }
}

package com.qf.b_inner;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;


class People {
    String name;
    int age;

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

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

public class Demo5 {
    public static void main(String[] args) {

        Set<People> set1 = new TreeSet<>(new Comparator<People>() {
            @Override
            public int compare(People o1, People o2) {
                int num1 = o1.age - o2.age;
                return num1;
            }
        });
        set1.add(new People("狗蛋", 12));
        set1.add(new People("狗蛋1", 1));
        set1.add(new People("狗蛋2", 2));
        set1.add(new People("狗蛋3", 22));
        System.out.println(set1);
    }
}

真实开发的时候,方法的参数是一个接口。平常写法是用一个类去实现它,但是现在直接在

调用方法的时候,直接new 接口。new的同时要重写抽象方法。再调用重写的方法即可

3.Map集合

开发经常用!!!

Map也是用来存储数据。存储数据的形式和List Set是不同的!!!

双边队列

Interface Map<K,V>

K: key 键

V: value 值

意味着咱们map集合存数据的时候,是以键值对的形式存储的!!!

0001====张三

0002====狗蛋

0003====李四

将键映射到值的对象。 地图不能包含重复的键; 每个键可以映射到最多一个值

HashMap 是Map接口实现类

增:
	V put(K k, V v); 添加一个键值对的数据到集合中
	void putAll(Map<? extends K,? extends V> m);  添加一个map集合到另外一个map集合中
	
删:
	V remove(Object key);  通过键删除值,返回值是被删除的值
	void clear(); 清空
	
改:
	V put(K k, V v);和添加类似,只有当键存在的时候,将v覆盖
		当键存在的时候,会修改,当键不存在的时候,直接添加了。
	V replace(K k, V v);当键存在的时候可以修改。当键不存在的时候,返回的null
查:【重点】
	int size(); 查看map集合中的元素的个数
	boolean isEmpty(); 判断集合是否为空  如果为空就是true  如果不为空就是false
	boolean containsKey();  集合中是否包含键
	boolean containsValue(); 集合中是否包含值
	
	以下几个方法比较重要!!!
	V get(K key);  通过键获取值
	Set keySet();  获取map集合中的键,将键存到set集合中。因为键不能重复,set集合刚好不能存重复的值的
	Collection<V>  values(); 获取集合中的值的!!!!存到Collection集合中
	Set<Map.Entry<K,V>>	entrySet();将键值对封装给Map.entry  存到了Set集合中了
		

package com.qf.c_map;

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

/**
 * description:
 * 公司:千锋教育
 * author:博哥
 * 公众号:Java架构栈
 */
public class Demo1 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("01", "狗蛋");
        map.put("02", "张三");
        map.put("03", "狗磊");
        System.out.println(map);
        //{01=狗蛋, 02=张三, 03=狗磊}
        //01=狗蛋  键值对
        Map<String, String> map1 = new HashMap<>();
        map1.put("04", "狗蛋");
        map1.put("05", "张三");
        map1.put("06", "狗磊");
        map1.put("09", "狗磊");
        map.putAll(map1);
        System.out.println(map);
        //{01=狗蛋, 02=张三, 03=狗磊, 04=狗蛋, 05=张三, 06=狗磊}
        System.out.println(map.remove("03"));//狗磊
        System.out.println(map);//{01=狗蛋, 02=张三, 04=狗蛋, 05=张三, 06=狗磊}


        System.out.println(map.replace("08", "张三"));
        System.out.println(map);
        System.out.println(map.size());//6
        System.out.println(map.isEmpty());//false

        System.out.println(map.containsKey("09"));//true
        System.out.println(map.containsKey("19"));//false
        System.out.println(map.containsValue("狗蛋"));//true


        System.out.println(map.get("01"));//狗蛋
        Set<String> strings = map.keySet();
        System.out.println(strings);
        for (String string : strings) {
            System.out.println(string);
        }
        Collection<String> values = map.values();
        System.out.println(values);//获取的是值

        //拿一个键值对出来,不要单独的键
        Set<Map.Entry<String, String>> entries = map.entrySet();
        // Map.Entry<K,V> 就是Java封装好的键值对的对象
        for (Map.Entry<String, String> entry : entries) {
            System.out.println(entry);
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
            System.out.println("=====");
        }

    }
}

今天的作业:

1.hashMap分析    word
2.编程题
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值