带你走进java.第十五章.HashSet集合的去重,TreeSet集合的排序不去重,双列集合Map

Set集合

LinkHashSet

1.特点: 在HashSet的基础上多了一个有序的特点
  Linked  有链表的结构  有序
  有序: 存储的顺序  就是  打印顺序
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("v");
set.add("m");
set.add("a");
set.add("b");
set.add("c");
set.add("d");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
    String string = (String) iterator.next();
    System.out.println(string);
}

输出结果:
v
m
a
b
c
d

利用Set集合特性, 去重List集合

// 利用Set集合
// 去除ArrayList集合中的重复元素(操作原ArrayList)
// ArrayList 保存a a, b b, c c, d d
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("c");
list.add("d");
list.add("d");
// 1.创建set集合  去重
LinkedHashSet<String> set = new LinkedHashSet<>();
// 2.利用set集合 addAll list集合元素 ,达到去重目的
set.addAll(list);
// 3.清空list集合
list.clear();
// 4.再将Set集合元素还给list集合
list.addAll(set);
System.out.println(list);

TreeSet

1.TreeSet特点: 无序  无下标  不重复
  特有功能: 排序
// 举例: TreeSet的去重和排序

// 创建TreeSet  保存4个数字  查看打印结果
    TreeSet<Integer> set = new TreeSet<>();
    set.add(11);
    set.add(22);
    set.add(44);
    set.add(33);
    set.add(22);
    System.out.println(set);
输出结果:
      [11,22,33,44] 

TreeSet的排序原理
1️⃣
(泛型是自定义类: 先让自定义类实现Comparable接口,再重写compareTo方法)
2️⃣
(泛型是系统类时: 重新定义一个类实现Comparator比较器接口,重写compare方法;
注意: 在声明这个集合时,要将重新自定义的类对象 添加到集合TreeSet的构造方法中)


//  举例 : 自定义类  在TreeSet集合中的排序
  自定义类在TreeSet排序顺序
 1.实现Comparable接口;
 2.实现接口中的方法;
 3.编写你的排序规则(重写CompareTo方法)

// 自定义类
class Person implements Comparable<Person>{
private String name;
private int age;
public Person() {
    super();
}
public Person(String name, int age) {
    super();
    this.name = name;
    this.age = age;
}
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;
}
@Override
public String toString() {
    return "Person [name=" + name + ", age=" + age + "]";
}
    /*
     *  实现接口中的比较方法compareTo()
     *  返回 0 只有一个元素(不存储)
     *  正数  按正序(正的存储顺序)输出
     *  负数  按倒序(倒的存储顺序)输出
     *  
     *  TreeSet
     *  二叉树排序 
     *  存规则
     *  1.比我小的数 放我的左边(返回负数时效果)
     *  2.比我大的数 放我的右边(返回正数时效果)
     *  3.不存(返回0)
     *  取规则
     *  从小到大 升序输出
     */
    @Override
    public int compareTo(Person o) {
        // 重新编写 比较的规则
        // 按年龄比较  this 和 传入的参数
        // 主要按年龄,次要按姓名(年龄相同,就比较姓名)
        int num1 = this.getAge() - o.getAge();
        if (num1 == 0) {
            int num2 = this.getName().compareTo(o.getName());
            return num2;
        }else {
            // 将返回值 赋值不等于0,可使集合不去重,并按升序排序
            return 1;
        }

// 将 自定义类对象 传入TreeSet集合中
// TreeSet保存4个人
Person person1 = new Person("1",11);
Person person2 = new Person("2",22);
Person person3 = new Person("3",33);
Person person4 = new Person("4",44);
TreeSet<Person> set = new TreeSet<>();
set.add(person1);
set.add(person2);
set.add(person3);
set.add(person4);
System.out.println(set);

这里写图片描述


// 举例 :  系统类(不能重写系统类中的方法)  在TreeSet方法中的排序
 系统类在TreeSet排序顺序
 1.自定义类实现Comparator 比较器 接口
 2.自定类中可以编写比较规则
 3.将比较的规则实现类对象  直接传入到 TreeSet构造方法当中


// 系统类更改比较规则 按字符串长度
// TreeSet保存四个字符串
// 按字符串长度排序 

// 自定义类
 class CompareLength implements Comparator<String>{

    @Override
    public int compare(String o1, String o2) {
        // TODO Auto-generated method stub
        int num = o1.length() - o2.length();    
        int rel = num == 0 ? o1.compareTo(o2) : num;
        return rel == 0 ? 1 : rel;// 不让删除相同的字符串.强行返回1
    }

}

// 将自定义类传入 TreeSet集合中
TreeSet<String> set = new TreeSet<>(new CompareLength()); 
/*第三步:将比较的规则实现类对象  直接传入到 TreeSet构造方法当中*/
set.add("1111");
set.add("33");
set.add("4");
set.add("222");
System.out.println(set);
输出结果:
[4,33,222,1111]

//  TreeSet集合 不去重排序练习 (用来熟悉步骤)
// 练习1.
//  在一个集合ArrayList
//  中存储了无序并且重复的字符串
//  要求 排序,而且还不能去除重复(用比较器)
//  主要按字符串长度比较 次要按字符串比
    ArrayList<String> list = new ArrayList<>();
    list.add("wanglong");
    list.add("dong");
    list.add("liu");
    list.add("wangjun");
    list.add("dong");
    TreeSet<String> set = new TreeSet<>(new CompareLength());
    set.addAll(list);
    System.out.println(set);
    输出结果:
    [liu, dong, dong, wangjun, wanglong]

// 练习2
//  键盘接收一个字符串, 
//  程序对其中所有字符进行排序 要求保留重复的   

class CompareChar implements Comparator<Character>{

    @Override
    public int compare(Character o1, Character o2) {
        int num = o1.compareTo(o2);// 或者 o1 - o2
        return num == 0 ? 1 : num;
    }   

}

    System.out.println("请输入一个字符串: ");
    Scanner scanner = new Scanner(System.in);
    String string = scanner.nextLine();
    TreeSet<Character> list = new TreeSet<>(new CompareChar());
    for (int i = 0; i < string.length(); i++) {
        list.add(string.charAt(i));
    }
    System.out.println(list);


// 练习3
//  程序启动后, 可以从键盘输入接收多个整数,
//  直到输入quit时结束输入. 
//  把所有输入的整数降序排列打印  

class CompareInt implements Comparator<Integer>{

    @Override
    public int compare(Integer o1, Integer o2) {
        int num = - (o1 - o2);
        return num == 0 ? 1 : num;
    }


}

TreeSet<Integer> set = new TreeSet<>(new CompareInt()); 
System.out.println("请输入一个整数(quit结束): ");
Scanner scanner = new Scanner(System.in);           
while (true) {
    // 接受用户输入
    String string = scanner.nextLine();
    // 判断是否停止
    if (string.equals("quit")) {
        break;
    }
    // 字符串转数字
    int num = Integer.parseInt(string);
    // 添加到集合
    set.add(num);
}
System.out.println(set);

双列集合Map

1.双列集合
Map(双列集合的父接口)
特点: 1️⃣以 键值对的形式 来存储数据   key(键值)---value(值)
     2️⃣键值是唯一的 (键值不能重复,输入 重复键值 会覆盖原有的value值)

这里写图片描述

HashMap与HashSet有关系吗?
有关系,HashSet 依赖 HashMap
实际上 向HashSet中添加元素 相当于 向map中添加元素,只不过设置value=null

2.双列集合的建立  put(key,value)
// Map的创建
HashMap<String,Integer> map = new HashMap<>();
// 添加键值对元素
// put方法返回值是 该键被覆盖的value值
Integer v1 = map.put("张三", 23);
Integer v2 = map.put("李四", 20);
Integer v3 = map.put("王五", 21);
Integer v4 = map.put("赵六", 22);
Integer v5 = map.put("张三", 2018);
System.out.println(map);
System.out.println(v1);
System.out.println(v2);
System.out.println(v3);
System.out.println(v4);
System.out.println(v5);
输出结果:
{张三=20, 李四=22, 王五=2018, 赵六=21}
null
null
null
null
23
3.双列集合的方法
/*
* map 方法
* 包含 key
* 包含 value
* 获取所有key的Set集合
* 获取所有value集合
* 通过key删除整个键值对
* 清空map
*/
 HashMap<String,Integer> map =  new HashMap<>();
map.put("明明", 23);
map.put("东东", 20);
map.put("生生", 21);
map.put("柳柳", 22);
// 判断map中是否包含 key或value
boolean b1 = map.containsKey("明明");
boolean b2 = map.containsValue(15);
System.out.println(b1);
System.out.println(b2);
// 获取所有key的Set集合(核心方法)  keySet()
Set<String> set = map.keySet();
System.out.println(set);
// 获取所有value集合  values()
Collection<Integer> set1 =  map.values();
System.out.println(set1);
// 通过key删除整个键值对  会返回value值
Integer a = map.remove("明明");
System.out.println(a);
// 清空map
map.clear();
System.out.println(map);
// 通过key值寻找value值
Integer c = map.get("明明");
4.双列集合的遍历-迭代器 或 Entry对象(键值对)
// 通过迭代器遍历
HashMap<Person, String> map = new HashMap<>();
map.put(new Person("明明", 23), "安徽");
map.put(new Person("东东", 15), "上海");
map.put(new Person("生生", 45), "广东");
map.put(new Person("柳柳", 34), "江西");
// 首先取出所有key的集合
Set<Person> keyset = map.keySet();
// 取出集合中的迭代器
Iterator<Person> iterator = keyset.iterator();
while (iterator.hasNext()) {
    // 遍历所有key
    Person key = (Person) iterator.next();
    // 利用key取出对应value
    String value = map.get(key);
    System.out.println("key = " + key  + " value = " + value);
}
// 利用Entry对象来遍历map   entrySet() 
// Entry对象中封装了 一个键值对 对象
// 一个key 一个对应的value
HashMap<String, Integer> map = new HashMap<>();
map.put("明明", 23);
map.put("东东", 15);
map.put("生生", 45);
map.put("柳柳", 34);
// 获取所有Entry对象的Set集合
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
// 取出迭代器
Iterator< Map.Entry<String, Integer>> a = entrySet.iterator();
// 遍历所有entry对象
while (a.hasNext()) {
    // 取出每一个entry对象
    Map.Entry<String, Integer> entry = (Map.Entry<String, Integer>) a.next();
    // 打印
    System.out.println("key = " + entry.getKey()  + " value = " + entry.getValue());
}
5.HashMap和LinkedHashMap的对比

  HashMap 无序
  LinkedHashMap 有序(存储顺序)

附加:Collections的工具类

 集合的工具类  Collections(静态方法)
 // 随机顺序(洗牌方法)
Collections.shuffle(集合对象);

// 排序方法
// 排 自定义对象类型行不行?
// 需要实现comparable接口或比较器
Collections.sort(集合对象);

// 二分查找   没有这个值,返回  -(该存索引 + 1)
int index = Collections.binarySearch(集合对象, 查找对象);

// 集合反转
Collections.reverse(集合对象);

猜你喜欢

转载自blog.csdn.net/qq_35368276/article/details/82501411