集合框架

点击上方蓝色文字,加关注,获取更多推文

哈喽大家好,小哥来了,昨天小哥累了休息了一下,就没有推文了,那今天补上哈,老套路,看标题!

来吧:谈谈自己适不适合干软开。

这是母校的图书馆哦

  • Set:包括HashSet和TreeSet,HashSet又包括linkedHashSet,同时Set也是派生于Collection,也是一个单列集合

    • 特点:无序且不可存放重复的元素,连null都必须存一份,底层是Map集合

  • HashSet:无序,线程不安全,效率高(底层用的是HashMap,在1.8之前是基于哈希表的,在1.8之后值基于哈希表+红黑树),默认大小是16,加载因子是0.75,每次扩容1倍。

  • TreeSet:可用于排序,底层是TreeMap(基于红黑树)

  • LinkedHashSet:有序,这个的有序是链表的特性导致的,底层是基于哈希表+红黑树+双向链表

Set set = new HashSet();
    set.add("1");
    set.add("d");
    set.add("a");
    set.add("125");
    set.add("125");
    set.add(null);
    set.add(null);
    System.out.println(set);
    运行结果:[null, 1, a, d, 125]
    无序,会将重复的元素保留一个,不存在索引,因为是链式的

设计一个list,将里面重复的元素去掉(从list到set可以去掉重复的元素,从set到list可以取到元素的索引,实用性非常高):代码如下

Set set = new HashSet();
    List list = new ArrayList();
    list.add("hhhhh");
    list.add("hhhhh");
    list.add("hhhhh");
    list.add("hhhhh");
    list.add("458");
    list.add("cccc");
    list.add("cccc");
    set.addAll(list);
    System.out.println("去掉重估之前"+list);
    System.out.println("去掉重复之后"+set);
    运行结果:
    去掉重估之前[hhhhh, hhhhh, hhhhh, hhhhh, 458, cccc, cccc]
    去掉重复之后[hhhhh, 458, cccc]

判断list中元素是否相同:

public class Entrance {
  public static void main(String[] args) {
    List list=new ArrayList();
    list.add(new PersonTwo("李四",20));
    boolean b=list.contains(new PersonTwo("李四", 20));
    System.out.println(b);
  }
}
class PersonTwo{
  String nameString;
  int age;
  public PersonTwo(String nameString, int age) {
    this.nameString = nameString;
    this.age = age;
  }
  @Override
  public String toString() {
    return "Person [nameString=" + nameString + ", age=" + age + "]";
  }
}
运行结果:false

为什么是false尼:因为此时只对比的是地址值,以上代码明显就是两个不同的地址。怎样可以让false变为true 请看下方代码,解析看注释

public class Entrance {
  public static void main(String[] args) {
    List list=new ArrayList();
    list.add(new PersonTwo("李四",20));
    boolean b=list.contains(new PersonTwo("李四", 20));
    System.out.println(b);
  }
}
class PersonTwo{
  String nameString;
  int age;
  public PersonTwo(String nameString, int age) {
    this.nameString = nameString;
    this.age = age;
  }
  @Override
  public String toString() {
    return "Person [nameString=" + nameString + ", age=" + age + "]";
  }
  @Override
  public boolean equals(Object obj) {
    if(this==obj) {
      return true;
    }
    if(obj instanceof PersonTwo) {
      PersonTwo personTwo = (PersonTwo)obj;
      if(this.age==personTwo.age && this.nameString.equals(personTwo.nameString)) {
        return true;
      }else {
        return false;
      }
    }else {
      return false;
    }
  }
}
运行结果:true
原因就是我自定义的类中没有覆写Object中的equals方法,因此,当我覆写这个方法后,我规定,当所有属性都相等时则表示为true

下一个话题:Set集合可以去重的原因:

  • 是因为hashCode和equals方法

  • 首先判断两个对象的hashCode值(一个十六进制的地址值,是根据对象的地址以及属性算出来的,也叫散列值)是否相等,如果相等,判断equals是否为true,都满足,才会认为时一个对象,否则不是一个对象

二话不说,上例子

public class Entrance {
  public static void main(String[] args) {
    Set set = new HashSet();
    set.add(new PersonTwo("王五", 20));
    set.add(new PersonTwo("王五", 20));
    System.out.println(set.toString());
  }
}


class PersonTwo {
  String nameString;
  int age;


  public PersonTwo(String nameString, int age) {
    this.nameString = nameString;
    this.age = age;
  }


  @Override
  public String toString() {
    return "Person [nameString=" + nameString + ", age=" + age + "]";
  }


  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj instanceof PersonTwo) {
      PersonTwo personTwo = (PersonTwo) obj;
      if (this.age == personTwo.age && this.nameString.equals(personTwo.nameString)) {
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
}
运行结果:[Person [nameString=王五, age=20], Person [nameString=王五, age=20]]


此时是set但是没有去重,为什么尼:

看下面代码

public class Entrance {
  public static void main(String[] args) {
    Set set = new HashSet();
    set.add(new PersonTwo("王五", 20));
    set.add(new PersonTwo("王五", 20));
    System.out.println(set.toString());
  }
}


class PersonTwo {
  String nameString;
  int age;


  public PersonTwo(String nameString, int age) {
    this.nameString = nameString;
    this.age = age;
  }


  @Override
  public String toString() {
    return "Person [nameString=" + nameString + ", age=" + age + "]";
  }


  
  @Override
  public int hashCode() {
    //这个地方一般是认为设定的,我还可直接return this.nameString
    return this.nameString.hashCode()+this.age;
  }


  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj instanceof PersonTwo) {
      PersonTwo personTwo = (PersonTwo) obj;
      if (this.age == personTwo.age && this.nameString.equals(personTwo.nameString)) {
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
}
运行结果:[Person [nameString=王五, age=20]]
因为我覆写了Object中的hashCode了

为什么在基本数据类型中,set可以去掉重复-------------------------------------------------------------------------------------------------这个问题,大家去思考吧,思考完了可以公众号恢复小哥,有惊喜哦。

下一个话题:TreeSet:可以自动帮助我们排序,底层基于hashMap--基于红黑树,直接上例子:

Set treeSet=new TreeSet();
    treeSet.add(1);
    treeSet.add(6);
    treeSet.add(2);
    treeSet.add(8);
    treeSet.add(9);
    System.out.println(treeSet);
    运行结果:
    [1, 2, 6, 8, 9]

说到这里,小哥要普及一下数据结构的知识:

在二叉排序树中:他的遍历方式有三种

  • 前序:也就是根左右,先根后左再右

  • 中序:也就是左根右,先左后根再右

  • 后续:也就是左右根,先左后右再根

那TreeSet默认的是中序遍历,下面小哥来画一个图:就拿代码中的例子,如下:

其他的大家自己研究了:

这里有道题:

先序:2 3 6 4 7 9 8 

中序:6 3 2 9 7 4 8 

后续:?

写出后续发送公众号有惊喜哦----------------------------------------------

  • 下一个话题:

    • 方式一:TreeSet通过实现Comparable接口覆写compareTo进行排序:

public class Entrance {
  public static void main(String[] args) {
    Set treeSet=new TreeSet();
    treeSet.add(new PersonTwo("张胜男", 20));
    treeSet.add(new PersonTwo("李嘉诚", 25));
    treeSet.add(new PersonTwo("高斯", 29));
    treeSet.add(new PersonTwo("四哦分",30));
    treeSet.add(new PersonTwo("张是", 50));
    System.out.println(treeSet);
  }
}
class PersonTwo implements Comparable{
  String nameString;
  int age;
  public PersonTwo(String nameString, int age) {
    this.nameString = nameString;
    this.age = age;
  }
  @Override
  public int compareTo(Object o) {
    if(o instanceof PersonTwo) {
      PersonTwo personTwo = (PersonTwo)o;
      if(this.age>personTwo.age) {
        return 1;
      }else if(this.age==personTwo.age) {
        return 0;
      }else {
        return -1;
      }
    }else {
      return -1;
    }
  }
  @Override
  public String toString() {
    return "PersonTwo [nameString=" + nameString + ", age=" + age + "]";
  }
}
运行结果:
[PersonTwo [nameString=张胜男, age=20], PersonTwo [nameString=李嘉诚, age=25], PersonTwo [nameString=高斯, age=29], PersonTwo [nameString=四哦分, age=30], PersonTwo [nameString=张是, age=50]]


  •    方式二:通过实现Comparator接口覆写compare方法进行比较排序

这样的好处是有效的分离对象和比较规则。代码如下:

public class Entrance {
  public static void main(String[] args) {
    Set treeSet=new TreeSet(new MyComparator());
    treeSet.add(new PersonTwo("张胜男", 20));
    treeSet.add(new PersonTwo("李嘉诚", 25));
    treeSet.add(new PersonTwo("李嘉诚", 25));
    treeSet.add(new PersonTwo("高斯", 29));
    treeSet.add(new PersonTwo("四哦分",30));
    treeSet.add(new PersonTwo("张是", 50));
    System.out.println(treeSet);
  }
}
class MyComparator implements Comparator{
  @Override
  public int compare(Object o1, Object o2) {
    if(o1 instanceof PersonTwo && o2 instanceof PersonTwo) {
      PersonTwo personTwo = (PersonTwo)o1;
      PersonTwo personTwo2 = (PersonTwo)o2;
      if(personTwo.age>personTwo2.age) {
        return 1;
      }else if(personTwo.age==personTwo2.age) {
        if(personTwo.nameString.compareTo(personTwo2.nameString)>0) {
          return 1;
        }else if(personTwo.nameString.compareTo(personTwo2.nameString)==0) {
          return 0;
        }else {
          return -1;
        }
      }else {
        return -1;
      }
    }else {
      return -1;
    }
  }
}
class PersonTwo{
  String nameString;
  int age;
  public PersonTwo(String nameString, int age) {
    this.nameString = nameString;
    this.age = age;
  }
  @Override
  public String toString() {
    return "PersonTwo [nameString=" + nameString + ", age=" + age + "]";
  }
}
运行结果:
[PersonTwo [nameString=张胜男, age=20], PersonTwo [nameString=李嘉诚, age=25], PersonTwo [nameString=高斯, age=29], PersonTwo [nameString=四哦分, age=30], PersonTwo [nameString=张是, age=50]]

总结一下:

comparable:使对象的属性在本类中实现比较并排序

comparator:使对象和这种排序规则分离。

终于总结结束了,一首西安人的歌送给大家,听着歌声,大家晚安,晚安,晚安

动起你的小手,右下方点赞点在看,让我们一起站在风口浪尖,听西安人的歌

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值