java学习笔记017
2021/6/18 20:59:05
本文主要是介绍java学习笔记017,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一.Set 接口
1.基本概念
Set : 是 Collection 的子接口, 特点是无序不可重复(自动去重),
新增方法: Set< E > of(E... elements)返回包含任意数量元素的不可修改集合。 无序: 存放的顺序与内部真实存储的顺序不一致(内部有自己存储的规则). 去重: 两个数据调用equals方法返回值true,相同需要去重,false不同可以添加.
遍历方式只有两种 :1.for each 2.迭代器 iterator
import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class Set { public static void main(String[] args) { Set<Integer> set = new HashSet<>(); set.add(123);//自动去重只能存进去一个 set.add(123); System.out.println(set);//[123] Set<String> set2 = new HashSet<>(); set2.add("哈哈"); set2.add("ab"); set2.add("呵呵"); set2.add("bd"); set2.add("a"); set2.add("吼吼"); System.out.println(set2);//[ab, a, bd, 哈哈, 呵呵, 吼吼]真实的存储顺序与实际存入顺序不同, 按照集合内部自己的排序方式. //for each遍历 int i= 1; for (Object obj:set2) { if(i==set2.size()){ System.out.print(obj); break; } System.out.print(obj+" "); i++; } //迭代器遍历 Iterator it = set2.iterator(); while (it.hasNext()){ System.out.print(it.next()+" "); } //static <E> Set<E> of(E... elements) 返回包含任意数量元素的不可修改集。 Set<Integer> set3 = Set.of(1,2,3,4,5); } }
2.HashSet实现类
HashSet : Set 接口的实现类.无新增功能,无序不可重复. 底层结构: 哈希表 (数组+链表+红黑树) ->是由HashMap维护. 优点 : 查询,增删效率较高. 应用场景: 实现不存储相同数据,查询,增删效率较高的时候建议使用HashSet
哈希表 : 数组+链表+红黑树
存储数据的步骤:
-
数据首先传给 hashcode ( ) 方法, hashcode 方法默认根据对象的地址通过hash指定的算法计算后返回一个int类型的整数.
-
得到返回的int整数后,通过指定的hash算法计算数据要存在数组的哪个索引位置,不同的jdk版本哈希算法不尽相同,一般会尽量分散在数组的每个索引位置.
-
确定索引位置后,如果在指定的索引位置中没有链表及节点存在,直接把这个数据作为链表头存入这个索引位置, 如果已经有链表存在, 就需要遍历这个链表的每一个节点,调用 equals 方法比较这个数据与链表中的节点数据是否相等,如果每一个都不相等就把这个数据存入这个链表的最后.
-
当链表长度>8并且数组的总长度>64的时候,会把链表变为红黑树.
注意: 前提是重写hashcode与equals方法,让它根据成员变量值去计算而不是对象地址.equals相等,hashcode的结果一定相等; hashcode结果一样, equals 不一定相等.
import java.util.HashSet; import java.util.Objects; public class HashSet { public static void main(String[] args) { HashSet<Person> hash = new HashSet(); hash.add(new Person("天一","男",18)); hash.add(new Person("天二","男",23)); hash.add(new Person("天三","男",19)); hash.add(new Person("天四","男",24)); hash.add(new Person("天五","男",25)); hash.add(new Person("天五","男",25)); //两个天五只能存进去一个 for (Person p:hash) { System.out.println(p); } } } //自定义类引用数据类型 class Person{ private String name; private String gender; private int age ; public Person() { } public Person(String name, String gender, int age) { this.name = name; this.gender = gender; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", gender='" + gender + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name) && Objects.equals(gender, person.gender); } @Override public int hashCode() { return Objects.hash(name, gender, age); } }
3. TreeSet 实现类
TreeSet : Set接口的实现类,无序不可重复.
3.1基本定义
底层结构: 红黑树(平衡二叉树). 特点: 自动做生序排序. 新增功能: 新增了一些能够比较的相关功能.
public class TreeSet { public static void main(String[] args) { TreeSet<Integer> set = new TreeSet<>(); set.add(5); set.add(2); set.add(1); set.add(3); set.add(4); System.out.println(set);[1,2,3,4,5] //E ceiling(E e) 返回此set中大于或等于给定元素的 null元素,如果没有这样的元素,则 null 。 System.out.println(set.ceiling(6));//没有大于6的,null //E first() 返回此集合中当前的第一个(最低)元素。 System.out.println(set.first()); //E last() 返回此集合中当前的最后一个(最高)元素。 System.out.println(set.last()); //E higher(E e) 返回此集合中的最小元素严格大于给定元素,如果没有这样的元素,则 null 。 System.out.println(set.higher(1));//从第一个开始比较拿出第一个比1大的值. //E pollFirst() 检索并删除第一个(最低)元素,如果此组为空,则返回 null 。 //E pollLast() 检索并删除最后一个(最高)元素,如果此集合为空,则返回 null 。 System.out.println(set.pollFirst());//删除第一个数 System.out.println(set.pollLast);//删除最后一个数 } }
3.2 比较器(比较规则)
在 TreeSet 存储自定义引用数据类型的数据时, 存储对象的排序与去重都需要指定比较规则.
按编写位置分为:内部比较器和外部比较器.在没有指明使用外部比较器(定制排序)的情况下,默认使用内部比较器(自然排序).
-
内部比较器 | 自然排序 :定义在需要存储的引用数据类型的类内部的一个指定的比较方式(方法).缺点是代码固定不够灵活.
步骤:1)让引用数据类型的类实现 Comparable 接口, 2)重写 Comparable 的 compareTo ( T o )方法,返回值为 int 类型. T1.compare( T2 ) .比较两个数据的大小, 当返回值为 0 时->T1 = T2 , 返回正数时-> T1 > T2 .返回负数时-> T1 < T2 .
-
外部比较器 | 定制排序 : 定义在要存储的引用数据类型的类外部的一个指定的比较规则(方法).
步骤:1)让引用数据类型的类实现 Comparator 接口, 重写 compare ( T t1, T t2)方法返回值为 int 类型. t1.compare( t2 ) .比较两个数据的大小, 当返回值为 0 时->t1 = t2 , 返回正数时-> t1 > t2 .返回负数时-> t1 < t2 .
import java.util.Arrays; import java.util.Comparator; public class TreeSet { public static void main(String[] args) { //指明外部比较器 //com 可简化为lambda表达式 (x,y)->x.getAge()-y.getAge() TreeSet<User> treeSet = new TreeSet<>(com); treeSet.add(new User("孙悟空","男",9999)); treeSet.add(new User("盖伦","男",30)); treeSet.add(new User("彦","女",6500)); treeSet.add(new User("赵信","男",32)); treeSet.add(new User("炙心","女",4300)); treeSet.add(new User("卡尔","男",9999)); //匿名内部类 Comparator<User> com = new Comparator<User>() { @Override public int compare(User o1, User o2) { if(o1.getGender().compareTo(o2.getGender())==0){ return o1.getAge()-o2.getAge(); } return o1.getGender().compareTo(o2.getGender()); } }; for (User u:users) { System.out.println(u); } } }
//数据类型的类实现Comparable接口,<User>表示只能比较这个类型的对象数据 public class User implements Comparable<User>{ private String name; private String gender; private int age ; public User() { } public User(String name, String gender, int age) { this.name = name; this.gender = gender; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", gender='" + gender + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; return age == user.age && Objects.equals(name, user.name) && Objects.equals(gender, user.gender); } @Override public int hashCode() { return Objects.hash(name, gender, age); } //重写compareTo(T o)方法.内部比较器 @Override public int compareTo(User o) { if(this.getName().compareTo(o.getName())==0){ if(this.getAge()-o.getAge()==0){ this.getGender().compareTo(o.getGender()); }else { return this.getAge()-o.getAge(); } } return this.getName().compareTo(o.getName()); } }
二.Map<K,V>接口
1.基本定义
Map<K,V> : 集合中的元素由键值对k-v组成, Map的无序与去重 由key决定 k: 可以为任意引用数据类型数据 --> Set 无序不可重复 v: 可以为任意引用数据类型数据 --> Collection 可重复无序 一个key只能对应一个value->映射关系, 可以根据key操作value
import java.util.HashMap; import java.util.Map; public class Map { public static void main(String[] args) { //创建Map集合,key存储int类型数据,value储存String类型数据 Map<Integer,String> map = new HashMap<>(); //V put(K key, V value) 将指定的值与此映射中的指定键相关联。 map.put(1001,"张三");//成对储存 map.put(1002,"李四"); map.put(1003,"王五"); System.out.println(map.put(1002,"LISA"));//重复的key,value值会被覆盖,返回被覆盖的值 System.out.println(map); //V get(Object key) 返回指定键映射到的值,如果此映射不包含键的映射,则返回 null 。 System.out.println(map.get(1001)); //boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回 true 。 //boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true 。 System.out.println(map.containsKey(1003)); System.out.println(map.containsValue("zhangsan")); //V remove(Object key) 如果存在,则从该映射中移除键的映射。 System.out.println(map.remove(1001)); System.out.println(map); } }
2.遍历方式
1.keySet 获取所有的key值,返回一个set集合.既可以获取到key,也可以获取到value. 2.values() 获取map集合中所有键值对的value,返回一个Collection集合.只能获取到value, 3.entrySet() 获取所有的键值对->Map.Entry 类型->表示一个键值对.
import java.util.*; public class Each { public static void main(String[] args) { //创建Map集合 Map<Integer,String> map = new HashMap<>(); map.put(1000,"天"); map.put(1001,"地"); map.put(1002,"人"); //1.keySet Set<Integer> keys = map.keySet(); for (Integer i :keys){ System.out.println(i+"<-->"+map.get(i)); } //2.values Collection<String> val = map.values(); for(String s:val){ System.out.println(s); } //3.entrySet Set<Map.Entry<Integer,String>> set = map.entrySet(); Iterator<Map.Entry<Integer,String>> it = set.iterator(); for(;it.hasNext();){ Map.Entry entry = it.next(); System.out.println(entry.getKey()+"<-->"+entry.getValue()); } } }
3.HashMap实现类
底层结构: 哈希表(数组+链表+红黑树).特点: 查询,增删效率较高.
扩容问题: 初始容量16,newCap = oldCap << 1 数组每次扩容原容量的两倍 DEFAULT_INITIAL_CAPACITY 初始容量 16 DEFAULT_LOAD_FACTOR : 默认加载因子 0.75 threshold : 扩容临界值 DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY
在使用HashMap存储自定义的引用数类型的数据时, 类型中应该重写hashcode方法(作为比较规则)实现去重和value的覆盖.
import java.util.Set; import java.util.TreeMap; public class HashMap { public static void main(String[] args) { HashMap<Teachers,String> hmap = new HashMap<>(); hmap.put(new Teachers("殷老师","java初级"),"5年");//被覆盖 hmap.put(new Teachers("李老师","大数据"),"6年"); hmap.put(new Teachers("裴老师","java高级"),"7年"); hmap.put(new Teachers("廖老师","java中级"),"8年"); hmap.put(new Teachers("卢老师","java鼓励师"),"9年"); hmap.put(new Teachers("殷老师","董事长"),"2年"); Set<Teachers> set = hmap.keySet(); for(Teachers s:set){ System.out.println(s+"<-->"+hmap.get(s)); } } }
4.TreeMap实现类
TreeSet底层是由TreeMap维护的,TreeMap 新增了一些有关于比较的方法. 底层结构: 红黑树. 特点: 自动做升序排序(根据key做升序)(key为自定义引用数据类型时需要比较器).
import java.util.Set; import java.util.TreeMap; public class TreeMap { public static void main(String[] args) { TreeMap<Teachers,String> tmap = new TreeMap<>((t1,t2)->t1.getName().compareTo(t2.getName())); tmap.put(new Teachers("殷老师","java初级"),"5年"); tmap.put(new Teachers("李老师","大数据"),"6年"); tmap.put(new Teachers("裴老师","java高级"),"7年"); tmap.put(new Teachers("廖老师","java中级"),"8年"); tmap.put(new Teachers("卢老师","java鼓励师"),"9年"); tmap.put(new Teachers("殷老师","董事长"),"2年"); Set<Teachers> set = tmap.keySet(); for(Teachers s:set){ System.out.println(s+"<-->"+tmap.get(s)); } } }
5.Properties 类
Properties : 存储字符串类型的键值对,特点是可以保存到流中或从流中加载。
优点 : 可以通过Properties实现软编码,从满足Properties特点的配置文件中读取数据,便于后期维护.
使用步骤: 1.定义一个(后缀名为.properties的)配置文件 xx.properties (键值对都是字符串), 在文件中保存键值对.(如: 张三=河南人) 2.创建Properties类型的对象,调用load从流中加载(输入流的数据源就是配置文件). 3.从配置文件中读取数据,加载使用.
import java.io.IOException; import java.util.Properties; public class Properties { public static void main(String[] args) throws IOException { Properties pro = new Properties(); //void load(InputStream inStream) 从输入字节流中读取属性列表(键和元素对)。 pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties")); System.out.println(pro.getProperty("username"));//zhangsan System.out.println(pro.getProperty("password"));//root } } db.properties : 配置文件 username=zhangsan password=root
这篇关于java学习笔记017的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27消息中间件底层原理资料详解
- 2024-11-27RocketMQ底层原理资料详解:新手入门教程
- 2024-11-27MQ底层原理资料详解:新手入门教程
- 2024-11-27MQ项目开发资料入门教程
- 2024-11-27RocketMQ源码资料详解:新手入门教程
- 2024-11-27本地多文件上传简易教程
- 2024-11-26消息中间件源码剖析教程
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器