Java小白学点东西(13)

本文介绍了TreeSet的特性,如何利用二叉树原理实现排序,以及如何处理自定义类对象的插入,包括重写Comparable接口和compareTo方法。通过Dog类实例演示了如何在TreeSet中存储和排序对象。

1.TreeSet

TreeSet的父接口是Set,存的值不可重复的,同时对存储的值进行了排序

排序的原理是二叉树原理

6  2  8  14  16  3  4  10  5  7  19
     6
  2       8
0    3         14
   0   4     10     16
     0   5  7   0  0   19
      
      是不平衡的树


      数据结构里面有一个红黑树,可以进行表数据的平衡等效率就会很低,会进行树的旋转


      如果单纯的进行查找的话,二叉树效率比较高


      底层的东西,不会暂时没有关系,先会敲代码吧


      如果有兴趣的可以度娘数据结构学学,数据结构是一门学科,内容比较多。
      
      

【注意事项】:

如果TreeSet集合中放的是八大基本数据类型的包装类例如Integer 以及String这个的时候不会报

错,但是如果TreeSet集合中放了一个自己定义的类的对象的话,会报错,报类转换异常的错误,那么有的同胞们就有问题了,怎么把自定义的对象放进去呢?

举个栗子:

创建一个狗类实现Comparable接口,泛型赋值为类Dog,重写其抽象方法compareTo,大家可以想到比较两个对象的方法就是(1)比较对象的年龄,(2)就是比较对象的名字,TreeSet集合会进行升序排序,那么怎么比较这两个呢?我们可以先比较他们的年龄,如果两只狗年龄一样,那么就去比较他们的名字,如果名字一样的话就可以认定为是一只狗了,compareTo方法是比较,小于返回负数,大于返回正数,相等返回0,我们可以在方法体内加一个if分支(本人这里用了一个三目运算节省代码量),以便进行比较和排序,然后写上它的构造方法,并且重写toString。

        接着在主函数里讲TreeSet实例化,并且通过add在集合中new几个可爱的狗狗,最后通过加强for循环(也可以直接sout打印出来,毕竟重写了toString方法嘛)进行遍历打印,代码以及结果如下:

import java.util.TreeSet;

class Dog implements Comparable<Dog>{
private String name;
private int age;

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

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

    @Override
    public int compareTo(Dog o) {
        int num = this.age-o.age;
        return num ==0 ? this.name.compareTo(o.name):num;
    }
}
public class Demo1 {
    public static void main(String[] args) {
        TreeSet<Dog> dogs = new TreeSet<>();
        dogs.add(new Dog("小白",12));
        dogs.add(new Dog("小黄",10));
        dogs.add(new Dog("小黑",10));
        dogs.add(new Dog("小白",12));
        dogs.add(new Dog("小蓝",9));
        for (Dog dog:dogs
             ) {
            System.out.println(dog);
        }
    }
}

2.匿名内部类【重点】

2.1基于抽象类的匿名内部类

        想必大家都知道,要想调用抽象类和接口中的抽象方法必须有实现类重写抽象方

法,接着在主函数里面将实现类实例化,再调用抽象方法,由于程序员们比较懒,于是

就出现了匿名内部类,就可以直接在主函数里面调用抽象方法,给大家举个栗子:

abstract class Test{
    abstract void test1();
}
interface MyTest{
    void test2();
}
public class Dome1 {
    public static void main(String[] args) {
        new Test() {
            @Override
            void test1() {
                System.out.println("我是匿名抽象内部类!!!");
            }
        }.test1();
        new MyTest() {
            @Override
            public void test2() {
                System.out.println("我是接口中的抽象方法!!");
            }
        }.test2();
    }
}

总结:

在真实开发中,方法的参数有可能是一个接口或者抽象类,怎么办?有两种解决方法

1.老老实实的在写一个类去继承或者实现,传给方法的参数

2.直接使用匿名内部类,直接实例化接口或者抽象类即可,但是一定去实现方法。

3.Map集合

3.1Map集合

集合:存放数据的

双边队列

Map<K, V>

K :键 key

V:值 value

0===>狗蛋 1=====》大黄 2======》旺财 3======》小黑

通过键可以取值

身份证号对应着咱们的本人

身份证号相当于键 本人相当于值

1101111111111111 ==》 张三本人

键值对

public interface Map<K,V> 在map集合中存放的数据都是键值对形式的数据

Map是一个接口

实现类HashMap<K,V> 底层是hash表,和HashSet特别象

存数据的时候,存储的依据是key,如果key一样的话,就不能再存进去了

实现类TreeMap<K,V> 底层是二叉树,可以对咱们存入的键进行排序

3.2Map接口下面常用方法

增:

put(K key, V value);传入的是对应的k和v数据类型,有一个泛型的约束。

putAll(Key k,Value v);将一个map集合放到另外一个map集合中 删:

remove(K key) ; 通过键删除值,返回的是被删除的那个值

改:

put(K key, V value);当key存在的时候,就修改,当key不存在的时候,就添加

查:【重要,而且方法还多】

int size();键值对有效的个数

boolean isEmpty();判断map结合是否为空

Set keySet();将map集合中键转为 Set集合了【偏难,有点难理解】

Collection values();将map集合中的值,转为了Collection集合对象

boolean containsKey(Object key);如果map集合中包含了输入的键,就返回true

boolean containsValue(Object value);如果map集合中包含了输入的值,就返回true


import java.util.*;

class Dog{
    private String name;
    private int age;
    private double price;

    public Dog(String name, int age, double price) {
        this.name = name;
        this.age = age;
        this.price = price;
    }

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

public class Demo1 {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<>();
        //HashMap是Map集合的实现类,通过多态父类引用指向子类对象来实例化
        map.put(2,"张三");
        map.put(1,"李四");
        map.put(5,"王五");
        map.put(12,"小白");
        map.put(78,"菠萝包");
        //map集合里面put方法是在map集合里增加键值对
        System.out.println("put的传值功能:"+map);
        Map<Integer, String> map1 = new HashMap<>();
        map1.put(45,"撒旦");
        map1.put(21,"上帝");
        map.putAll(map1);//讲map1集合放到map里面,注意两个集合的数据类型必须一样
        System.out.println("putAll将两个集合合并为一个集合:"+map);
        map.put(2,"李黑");
        System.out.println(""+map);
        map.remove(1);
        System.out.println(""+map);
        map.clear();
        System.out.println(""+map);
        Map<Integer, Dog> dog = new HashMap<>();//map集合传值给set集合和collection集合
        Dog dog1 = new Dog("大黄", 2, 100.00);
        dog.put(1,dog1);
        dog.put(2,new Dog("大黑",4,200.00));
        dog.put(3,new Dog("大白",6,300.00));
        System.out.println(dog);
        Set<Integer> keys = dog.keySet();//map集合的键值不能重复,所以用set集合转化
        System.out.println(keys);
        Collection<Dog> dogs = dog.values();//map集合的值可以重复,所以用collection集合转化,
        //我这里是传的类对象,自己想传什么都行,比如传String就在泛型里改为String就ok
        System.out.println(dogs);
        System.out.println(dog.containsKey(1));//查询是否有这个键
        System.out.println(dog.containsValue(dog1));//查询是否有这个值(对象)注意要查询的话,对象要实例化!
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇智波波奶茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值