Java零基础(十七)之Treeset知识点+Map

1.Set实现类TreeSet(重点)
实现排序的方式
1.自然排序法------存储对象的类实现Comparable接口
2.比较器法 ------带参构造方法传入比较器对象(Comparator)

1.1 验证原理-存储单个属性的对象

  class Person implements Comparable<Person>{
    
    
	String name;
	public Person(String name) {
    
    
		this.name=name;
	}
	
	@Override
	public String toString() {
    
    
		return "Person [name=" + name + "]";
	}

	@Override
	public int compareTo(Person o) {
    
    
		//按自己方式比较,认为姓名相同则确定唯一
		//compareTo方法与二叉树原理匹配的>0  ==0  <0--->升序排列
		//return this.name.compareTo(o.name);
		
		return o.name.compareTo(this.name);  //倒叙排列
		
		//return 0;  //如果返回0,只返回一个对象
	}
	
    
}
public class Test1 {
    
    
	public static void main(String[] args) {
    
    
		Set<Person> set = new TreeSet<Person>();
		set.add(new Person("zs")); //ClassCastException: Person cannot be cast to Comparable
		set.add(new Person("ls"));
		set.add(new Person("zs"));
		set.add(new Person("ww"));
		System.out.println(set);
	}
}

1.2 验证原理-存储多个属性的对象
TreeSet存储对象为两个属性:
分析:需要判断两个属性都一致则认为是同一个对象

//自然排序法—存储类型实现Comparable接口

class Student implements Comparable<Student>{
    
    
	String name;
	int    age;
	
	public Student(String name, int age) {
    
    
		this.name=name;
		this.age = age;
	}
	@Override
	public String toString() {
    
    
		return "Student [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int compareTo(Student o) {
    
    
		//排序规则:按年龄比较升序,如果年龄相同,则按姓名的降序
		/*if(this.age==o.age) { //年龄相同
			return o.name.compareTo(this.name); //姓名降序
		}else {
			return this.age-o.age; //年龄升序
		}*/
		
		//排序规则2:先按姓名的升序排,如果姓名相同,则按年龄的降序
		if(this.name.equals(o.name)) {
    
    
			return o.age-this.age;  //年龄的降序
		}else {
    
    
			return this.name.compareTo(o.name);
		}
		
	}
	
}

public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		Set<Student> set = new TreeSet<>();
		set.add(new Student("zs",20));
		set.add(new Student("ls",20));
		set.add(new Student("zs",18));
		set.add(new Student("ls",20));
		System.out.println(set);
	}
}

1.3 比较器法

//案例:TreeSet存储两个属性的对象,使用比较器方式

class Teacher{
    
    
	String name;
	int    age;
	public Teacher(String name,int age) {
    
    
		this.name = name;
		this.age  = age;
	}
	@Override
	public String toString() {
    
    
		return "Teacher [name=" + name + ", age=" + age + "]";
	}
	
	
}
public class Test3 {
    
    
	public static void main(String[] args) {
    
    
		Set<Teacher> set = new TreeSet<Teacher>(new Comparator<Teacher>() {
    
    

			@Override
			public int compare(Teacher o1, Teacher o2) {
    
    
				//规则: 先按姓名降序排列,如果姓名相同,在按年龄升序排列
				if(o1.name.equals(o2.name)) {
    
    
					return o1.age-o2.age;
				}else {
    
    
					return o2.name.compareTo(o1.name);
				}
				
			}
		});
		
		set.add(new Teacher("zs", 13));
		set.add(new Teacher("ls", 13));
		set.add(new Teacher("zs", 13));
		set.add(new Teacher("ls", 15));
		
		System.out.println(set);
	}
}

2.TreeMap集合(重点)

2.1 基本使用
Map接口:下面的实现类都实现了存储键值对的特点
存储特点: key无序,且唯一;value允许重复; 如果key重复,那么value会覆盖之前的
Map的实现类HashMap: 通过hash算法实现存储
通过源码分析可知:具体实现与HashSet一致的,因为HashSet就是通过HashMap完成的存储

public class Test1 {
    
    
	public static void main(String[] args) {
    
    
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("bb", 11);
		map.put("aa", 11);
		map.put("bb", 22);
		
		//常用方法:
		System.out.println(map.get("aa"));  //11
		System.out.println(map.containsKey("bb"));  //true
		System.out.println(map.containsValue(22));  //true
		Collection<Integer> coll = map.values();    //把所有value放到集合中
		System.out.println(coll);
		System.out.println(map);
		System.out.println(map.size());  //长度2
		
		//----遍历:无下标不能使用基本for-----
		//for(int i=0;i<map.size();i++) {}
		
		//Map集合进行遍历的是两个值,不能直接使用增强for遍历
		//for(Object o:map) {}
		
		//-------间接遍历: keySet--------
		Set<String> keys = map.keySet();
		for(String key:keys) {
    
    
			System.out.println(key+"-->"+map.get(key));
		}
		
		//-------间接遍历: entrySet--------
		Set <Entry<String, Integer>> set = map.entrySet();
		for(Entry<String, Integer> entry:set) {
    
    
			System.out.println(entry.getKey()+"==>"+entry.getValue());
		}
	}
}


2.2 HashMap存储自定义对象
hashMap存储自定义对象,验证存储原理
注意:后续的map存储的key往往是String类型,此处,为了验证原理,所以key存储了自定义对象

class Student{
    
    
	String name;
	public Student(String name) {
    
    
		this.name = name;
	}
	
	@Override
	public String toString() {
    
    
		return "Student [name=" + name + "]";
	}

	//如果我们认为属性一致,则为同一个对象,则需要重写hashCode与equals
	@Override
	public int hashCode() {
    
    
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
    
    
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (name == null) {
    
    
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
}
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		Map<Student, Integer> map = new HashMap<Student, Integer>();
		map.put(new Student("zs"), 13);
		map.put(new Student("ls"), 15);
		map.put(new Student("zs"), 18);
		
		System.out.println(map);
		
		
		//扩展说明:移除一个对象
		map.remove(new Student("ls"));  //移除时,重写了equals,也可以针对属性一致去移除
		
		System.out.println(map);
	}
}
  1. TreeMap集合

3.1 基本使用
TreeMap: Map接口的实现类
存储特点: key可排序,唯一 如果key重复,新的value替换旧的
分析TreeMap的存储原理:二叉树算法
说明:和TreeSet类似,因为TreeSet的具体实现是通过TreeMap完成的

public class Test1 {
    
    
	public static void main(String[] args) {
    
    
		Map<String, Integer> map = new TreeMap<String, Integer>();
		map.put("cc", 11);
		map.put("bb", 33);
		map.put("aa", 22);
		map.put("cc", 44);
		System.out.println(map);
		
		//循环遍历:
		Set<String> keys = map.keySet();
		for(String key:keys) {
    
    
			System.out.println(key+"-->"+map.get(key));
		}
		
		Set<Entry<String, Integer>> set = map.entrySet();
		for(Entry<String, Integer> entry:set) {
    
    
			System.out.println(entry.getKey()+"==>"+entry.getValue());
		}
	}
}

3.2 TreeMap存储自定义对象
验证原理:
TreeMap存储自定义对象,查看结果
结果会报错
解决方式:

  1. 自然排序法—>实现Comparable接口
  2. 比较器法----->构造方法传比较器对象(匿名内部类)
class Person implements Comparable<Person>{
    
    
	String name;
	int    age;
	public Person(String name, int age) {
    
    
		this.name = name;
		this.age = age;
	}
	@Override
	public int compareTo(Person o) {
    
    
		//比较规则:先比较姓名的升序,姓名相同,再比较年龄的降序
		if(this.name.equals(o.name)) {
    
    
			return o.age-this.age;
		}else {
    
    
			return this.name.compareTo(o.name);
		}
		
	}
	@Override
	public String toString() {
    
    
		return "Person [name=" + name + ", age=" + age + "]";
	}
	}
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		//Map<Person, Integer> map = new TreeMap<Person, Integer>();
		
		Map<Person, Integer> map = new TreeMap<Person, Integer>(new Comparator<Person>() {
    
    

			@Override
			public int compare(Person o1, Person o2) {
    
    
				//比较规则:先比较姓名的升序,姓名相同,再比较年龄的降序
				if(o1.name.equals(o2.name)) {
    
    
					return o2.age-o1.age;
				}else {
    
    
					return o1.name.compareTo(o2.name);
				}
				
			}
		});
		map.put(new Person("zs", 13), 66);
		map.put(new Person("ls", 13), 66);
		map.put(new Person("zs", 36), 11);
		map.put(new Person("zs", 13), 25);
		System.out.println(map);
	}
}

3.3 其他类的相关操作
其他类的比较及操作:
HashMap VS Hashtable
HashMap: 不安全,但效率高的集合,key和value可以使用null
Hashtable:线程安全,效率低的集合,key和value都不能使用null

Properties: 是Hashtable的子类,常用于加载配置信息中

HashMap VS TreeMap
从执行效率方面考虑,肯定选择HashMap效率更高
如果需要实现排序,才选择TreeMap

public class Test1 {
    
    
	public static void main(String[] args) throws FileNotFoundException, IOException {
    
    
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("aa", 11);
		map.put(null, 33);
		map.put("cc", null);
		System.out.println(map);
		
		Map<String, Integer> map2 = new Hashtable<String, Integer>();
		map2.put("aa", 11);
		//map2.put(null, 33);
		//map2.put("cc", null);
		System.out.println(map2);
		
		//Properties: 之前在System类中使用过
		//Properties properties = System.getProperties();  //获取系统的配置属性
		
		//加载配置文件信息:  user.properties
		Properties properties = new Properties();
		//new一个IO流的子类对象,加载到Properties中,这样properties就有值了
		properties.load(new FileInputStream("user.properties"));
		//往往key为已知的,获取value值
		System.out.println(properties.getProperty("name"));
		
	}
}

3.4 集合相关汇总

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45682261/article/details/125146615