ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JAVA基础-集合Set

2020-07-03 20:37:47  阅读:203  来源: 互联网

标签:Set JAVA String age add 集合 new public TreeSet


首先总结一下集合的体系:

集合 的体系:
------------| Collection 单例集合的根接口
----------------| List 如果是实现了List接口的集合类,具备的特点: 有序,可重复。
-------------------| ArrayList 底层是维护了一个Object数组实现的。 特点: 查询速度快,增删慢。
-------------------| LinkedList 底层是使用了链表数据结构实现的, 特点: 查询速度慢,增删快。
-------------------| Vector(了解即可) 底层也是维护了一个Object的数组实现的,实现与ArrayList是一样的,但是Vector是线程安全的,操作效率低。

----------------| Set 如果是实现了Set接口的集合类,具备的特点: 无序,不可重复。
-------------------| HashSet 底层是使用了哈希表来支持的,特点: 存取速度快.
-------------------| TreeSet 如果元素具备自然顺序 的特性,那么就按照元素自然顺序的特性进行排序存储。

Set

Set 集合,元素是无序的,而且不能重复的。

重点掌握 HashSet 实现类的使用。

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SetDemo {

	public static void main(String[] args) {
		Set s1=new HashSet<>();
		s1.add("ddd");
		s1.clear();
		s1.remove("ddd");
		Iterator i1 = s1.iterator();
	}
}

HashSet

HashSet的特点:

  1. 添加的元素是无序的。

  2. HashSet 不是同步的,如果多个线程同时访问一个 HashSet,比如在修改时,一定要手动通过代码来保证同步,也就是保证安全。

  3. 集合元素值可以是 null

一些基本的用法:

import java.util.HashSet;
import java.util.Iterator;

public class HashSetDemo {

	public static void main(String[] args) {
		//hashset  存储数据唯一(不可重复)   无序
		HashSet<String> hs=new HashSet<String>();
		hs.add("张三");
		hs.add("张三");
		
		System.out.println(hs);
		System.out.println(hs.size());
		
		//遍历  foreach   迭代器
		for (String string : hs) {
			System.out.println("foreach:"+string);
		}
		//
		Iterator<String> i1=hs.iterator();
		while(i1.hasNext()) {
			System.out.println("迭代器:"+i1.next());
		}
		
	}
}

另外,我们从下面的代码可以看出一些hashset的特性,在这里,我们想要让hashset存储数据时不重复存储(因为每new一个对象,其索引不一样,且hash值也不同,即使我们new出的两个对象包含同样的信息,hashset依然会判定为两个不同的对象),我们做两个操作:

  1. 重写public boolean equals(Object obj)方法

  2. 重写public int hashCode() 方法

这么做的原因是:
往 HashSet 集合中添加一个元素的时候,默认调用 hashCode() 方法得到该对象的 hashCode 值,用于决定该对象在 HashSet 中存放的位置。
如果两个元素,通过 equals() 方法比较返回 true,但 hashCode() 返回的值不一样,说明两个元素是不 一样的,则允许添加。
所以,HashSet 集合判断两个元素是否相等,就是通过 equals() 方法还有 hashCode 值也一起比较。将来,如果有需要自定义一些判断方法,则可以模仿这里的操作方式。

import java.util.HashSet;

//人类
public class Person{

	String name;
	int age;
	String sex;

	public Person(String name, int age, String sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
    
	@Override
	public int hashCode() {
	// TODO Auto-generated method stub
		return age;
	}
    
	//案例 主要对象中姓名 年龄  和性别是相同的 就判断同一个对象使用set保存后体现唯一性
	//根据性别 姓名 年龄
	@Override
	public boolean equals(Object obj) {
		Person p1=(Person) obj;
		if(this.sex.equals(p1.sex)) {
			if(this.name.equals(p1.name)) {
				if(this.age==p1.age) {
					return true;
				}
			}
		}

		return  false;
	}
	//alt +Shift+s 弹出窗口 
	public static void main(String[] args) {
		//需求 使用hashset集合 存储4个person对象 并打印输出出来 哈希吗值也有关系
		HashSet<Person> phSet=new HashSet<Person>();
		Person zhangsan=new Person("张三", 18, "男");
		Person zhangsan2=new Person("张三", 18, "男");

		Person lisi=new Person("李四", 18, "男");
		Person wangwu=new Person("王五", 18, "男");
		Person qianliu=new Person("钱六", 18, "男");
		phSet.add(zhangsan);
		phSet.add(lisi);
		phSet.add(wangwu);
		phSet.add(qianliu);
		phSet.add(zhangsan2);
		System.out.println(phSet);
	}

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

LinkedHashSet

LinkedHashSet 从名字上看,跟“链式”有关,它也是根据元素的 hashCode 值来决定元素的存储位置, 但还多使用链表来维护元素的顺序。

访问它的时候,会根据元素的添加顺序来访问集合中的元素,有个好处,访问时的性能会很好。

因为是链式的结构,在插入数据的时候,性能略差于 HashSet,插入元素时不建议使用。

import java.util.LinkedHashSet;

public class LinkedHashSetDemo {

	public static void main(String[] args) {
		//无序  唯一的
		//链表结构与哈希吗值都有关系
		//与hashset相比  访问快  插入慢
		//方法同 hashset一样用
		LinkedHashSet<String> lhs =new LinkedHashSet<String>();
		lhs.add("张三");
		lhs.add("张三");
		lhs.add("张三");
		lhs.add("张三");
		lhs.add("张三");
		System.out.println(lhs);
//		lhs.remove("zhangsan");
		
	}
}

public class TreeSetTest { 
    public static void main(String[] args) { 
        TreeSet nums = new TreeSet(); 
        // 向 TreeSet 中添加对象 
        nums.add(5); 
        nums.add(2); 
        nums.add(10); 
        nums.add(-9); 
        // 输出集合元素,看到集合元素已经处于排序状态 
        // 并没有按添加的先后顺序进行排列
        System.out.println(nums);
        // 输出集合里的第一个元素 
        System.out.println(nums.first()); 
        // 输出-9 
        // 输出集合里的最后一个元素 
        System.out.println(nums.last()); 
        // 输出10 
        // 返回小于4的子集,不包含4 (左闭右开)
        System.out.println(nums.headSet(4)); 
        // 输出[-9, 2] 
        // 返回大于5的子集,如果Set中包含5,子集中还包含5 (左闭右开)
        System.out.println(nums.tailSet(5)); 
        // 输出 [5, 10] 
        // 返回大于等于-3,小于4的子集。 
        // -3 < x < 4 
        System.out.println(nums.subSet(-3, 4)); 
        // 输出[2] 
    } 
}

TreeSet

不同于hashset是根据哈希值来存储元素,TrerSet借助了红黑树来存储对象,虽然不可索引,但是内部依然是按顺序排列的。

TreeSet 可保证元素处于排序的状态,所以 TreeSet 采用的是红黑树的数据结构来存储集合元素的。

排序规则有:自然排序(默认)和定制排序。

import java.util.TreeSet;

public class TreeSetDemo {

	public static void main(String[] args) {
		//存储红黑二叉树数据结构 会对数进行排序存储
		TreeSet ts=new TreeSet();
		ts.add(222);
		ts.add(13);
		ts.add(2);
		ts.add(33);
		ts.add(4);
		ts.add(1);
		System.out.println(ts);
		System.out.println("最高的"+ts.last());
		System.out.println("最小的"+ts.first());
		System.out.println("检索最小元素返回并删除"+ts.pollFirst());
		System.out.println("检索最大元素返回并删除"+ts.pollLast());
		System.out.println(ts);
		//遍历 foreach  迭代器
		
	}
}

TreeSet 会调用 compareTo(Object obj) 方法来比较元素之间的大小关系,按升序进行排列。

此方法属于 Comparable 接口,将返回一个整数值,实现该接口的类就可以用返回值来比较大小。

Comparable 接口,主要提供了比较大小的标准,有些将来会碰到的常用类:BigDecimal、 BigInteger、Character、Boolean、String 、Date、Time 等。 当我们在Treeset中插入一个我们自己写的对象的时候会报错,其原因就是TreeSet利用compareTo(Object obj) 方法来比较元素之间的大小,所以我们需要将我们要比较的对象实现Comparable 接口。

当 TreeSet 添加元素时,会调用 compareTo() 方法先去比较大小和根据红黑树去查找位置,如果通过

compareTo() 方法比较相等,就不能再添加了,所以下面的代码Set中只有一个元素。

下面是我们要放入TreeSet的对象,我们实现了Comparable<T>方法:

import java.util.Comparator;

public class Pet implements Comparable<Pet>{

	String name;
	String color;
	int age;
	public Pet(String name, String color, int age) {
		super();
		this.name = name;
		this.color = color;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Pet [name=" + name + ", color=" + color + ", age=" + age + "]";
	}
	//treeset比较方法  原理红黑二叉树数据结构
	@Override
	public int compareTo(Pet o) {
		return 0;
	}
}
import java.util.TreeSet;

public class TreeSetDemo2 {

	public static void main(String[] args) {
		TreeSet<Pet> ts=new TreeSet<Pet>();
		ts.add(new Pet("妮妮", "白色", 18));
		ts.add(new Pet("妮妮", "白色", 18));

		System.out.println(ts);
	}
}

同时呢,如果想要实现我们自定义的排序方式,可以利用内部类的方法来实现:

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

public class Pet2 {

	int age;
	
	
	public Pet2(int age) {
		super();
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "Pet2 [age=" + age + "]";
	}

	//
	
	public static void main(String[] args) {
//		TreeSet<Pet2> treeSet=new TreeSet<Pet2>();
//		treeSet.add(new Pet2(18));
//		treeSet.add(new Pet2(17));
//		treeSet.add(new Pet2(2));
//		System.out.println(treeSet);
		//方式2  定制排序
		TreeSet<Pet2> t2=new TreeSet<Pet2>(new Comparator<Pet2>() {

			@Override
			public int compare(Pet2 o1, Pet2 o2) {
				// TODO Auto-generated method stub
				//比较
				return o1.age>o2.age?-1:o1.age<o2.age?1:0;
			}
		});
		
		//降序
		t2.add(new Pet2(18));
		t2.add(new Pet2(1));
		t2.add(new Pet2(23));
		System.out.println(t2);
	}

}

标签:Set,JAVA,String,age,add,集合,new,public,TreeSet
来源: https://www.cnblogs.com/JeasonIsCoding/p/13232527.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有