Set 集合
List有序的集合 Set是无序的
有序:去除的顺序和添加的顺序是一样的
1,set中不能存储相同的数据
HashSet可以存储null值
//实例化Set集合 HashSet set=new HashSet(); set.add("23"); set.remove("123"); set.size(); set.add("23"); int size=set.size(); System.out.println(size);
set.add(new String("456")); set.add(new String("456"));//内容相同,但是是两个不同的实例2 size=set.size(); System.out.println(size);//1 //可以存储null值 set.add(null); size=set.size(); System.out.println(size); for(Object item:set){ System.out.println(item); }
2,Treeset红黑树
注意点:(1)jdk8以后,如果链表长度超过8,而且数组长度大于等于64时,自动转换成红黑树(数组+链表+红黑树)
(2)如果集合中存储的是自定义对象,必须重写hashCode和equals方法(原因:原来的hashcode和equals都是根据地址值进行比较,实用意义不大,需要重写,都采用属性值进行计算哈希值及进行相关比较)
中序遍历:左子树--->根节点--->右子树
Treeset遍历方式是中序遍历,内部使用二叉树 内部节点是可以比较的
同一个TreeSet对象中存储的内容应该是可比较的,默认情况下不能存储不同类型
TreeSet tset=new TreeSet(); //存入数据 tset.add(2); tset.add(200); tset.add(3); tset.add(88); tset.add(45); tset.add(72); tset.add(1); tset.add(99);
这段代码展示了`TreeSet`的使用,包括存储整数和自定义类的实例,以及如何实现比较逻辑以确保元素可以被正确排序。下面是代码的详细解释:
TreeSet tset = new TreeSet();
这里创建了一个`TreeSet`实例,它将根据元素的自然顺序进行排序。对于原始类型或实现了`Comparable`接口的类,`TreeSet`能够自动排序。
tset.add(2);
tset.add(200);
接下来,向`TreeSet`中添加了一系列整数值。由于整型实现了`Comparable`接口,`TreeSet`能够正确排序这些值。
for (Object item : tset) {
System.out.print(item + ",");
}
这部分代码遍历`TreeSet`并打印所有元素,输出将是已排序的元素列表。
Comparator<Student> com = (a, b) -> {
if (a.score == b.score) {
return 0;
}
return a.score > b.score ? 1 : -1;
};
这里定义了一个`Comparator`,用于比较`Student`类的实例。`Comparator`允许你定义元素的排序规则,即使这些元素没有实现`Comparable`接口。在这个例子中,比较逻辑基于`score`属性。
TreeSet<Student> ttset = new TreeSet<>(com);
创建了一个新的`TreeSet`,这次传递了上面定义的`Comparator`,以便能够正确排序`Student`对象。
ttset.add(stua); ttset.add(stub); // ...
向`TreeSet`中添加`Student`对象。由于传递了`Comparator`,`TreeSet`将根据`score`属性对这些对象进行排序。
for (Student stu : ttset) {
System.out.println(stu.score);
}
这部分代码遍历`TreeSet`并打印每个`Student`对象的`score`属性,输出将是按`score`升序排列的`score`值列表。
TreeSet<Student> tttset = new TreeSet();
创建另一个`TreeSet`,但这次没有传递`Comparator`。
tttset.add(stuaa);
尝试向`TreeSet`中添加`Student`对象。但是,因为`Student`类必须实现`Comparable`接口,否则`TreeSet`将无法排序这些对象。
class Student implements Comparable {
int score;
@Override
public int compareTo(Object o) {
// 实现比较逻辑
}
}
这是`Student`类的定义,它实现了`Comparable`接口,允许`TreeSet`根据`score`属性对`Student`对象进行排序。如果没有这个实现,编译器将报错,因为`TreeSet`需要一种方法来确定如何比较`Student`对象。
class AA extends Student {
// ...
}
这是一个扩展了`Student`类的新类`AA`,但是它没有重写`compareTo`方法。如果试图将`AA`对象添加到`TreeSet`中,它将使用从`Student`继承的`compareTo`方法进行比较。如果`AA`类添加了额外的属性或比较逻辑,可能需要重写`compareTo`方法以反映这些变化
Map 存储键值对 键就是名字 值是存储对象
一个map中只能有一个null值,是不能重复的;
value是可以重复的
1,通过存入的key获取存入的对象
Object obj=map.get("A1");//获取A1对应的value值 System.out.println(obj);
2,通过key删除键值对
Object rem_obj=map.remove("A1"); System.out.println("删除的value值:"+rem_obj);
3.是否包含key
map.containsKey("A1");
4.是否包含value值
map.containsValue("张三");
5,获取所有的key
Set setkey=map.keySet();
6.获取所有的value
Collection con=map.values();
HashMap的key只能有一个null值,value可以有多个null值
底层实现是数组加链表
HashMap的数组默认容量是16(stringBuffer的也是16)
扩容 :每次扩容2倍
扩容阈值为0.75,达到现有容量的0.75倍时就开始扩容
Hashtable是线程安全的,它的key和value都不允许使用null键,如果尝试添加会报异常
ConcurrentHashMap 线程安全 效率较高
package com.easy722;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class EasyMap {
//Map 存储键值对 键 就是名字 值 存储的对象
public static void main(String[] args) {
Map map=new HashMap();
map.put("A1","张三");
//可以通过存入的key获取存入的对象
Object obj=map.get("A1");//获取A1对应的value值
System.out.println(obj);
//通过key删除键值对
Object rem_obj=map.remove("A1");
System.out.println("删除的value值:"+rem_obj);
//是否包含key
map.containsKey("A1");
//是否包含value值
map.containsValue("张三");
//获取所有的Key
Set setkey=map.keySet();
//获取所有的value
Collection con=map.values();
//map的
map.put(null,null);//key可以是null,但不能是重复的
map.put("A1",null);//value是可以重复的
map.put("A1","张三");
System.out.println(map);
//TreeMap
//TreeMap的底层是TreeSet
//key是可比较的
//key不能是null值
Hashtable ht=new Hashtable();
ht.put("t1","张三");//它的value和key不能是null值
//是线程安全的集合
LinkedHashMap lMap=new LinkedHashMap();
lMap.put("","");
//ConcurrentHashMap 线程安全 效率较高
ConcurrentHashMap chm;
//HashMap 底层实现 是数组加链表
//16
HashMap hmap=new HashMap();
hmap.put("","");
//HashMap 的数组默认容量 16(StringBuffer也是)
//扩容 每次扩容2倍
//扩容阈值 0.75 达到现有容量的0.75倍就会出扩容
//(最小树化阈值是8)一个链达到8就对该链进行树化
//一支树上的元素低于6个,那么这个树就会退化成链
//最小树化容量阈值 64
//如果这个数组的长度没有达到64,优先扩容
//线程安全的Map Hashtable ConcurrentHashMap(性能优异 锁颗粒度比较小)
}
}
泛型: 广泛的数据类型
确保类型安全的一种途径
定义:在类和方法上都可以定义泛型
泛型类:返回的类型和传递的类型是相同的
public <E> E test(E e){
//返回的类型和传入的类型是相同的
return e;
}
泛型方法:可以在非泛型类中声明
public class MyClass {
public <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
}
类型不安全
类型转换时没有明确对象的数据类型进行强制数据类型转换会抛出ClassCaseException(类型转换异常)
规范一个数据类型,确保类型安全
泛型的检查用String,在编译的时候起作用
泛型的上限
//定义泛型的上限 extends
public static <J extends List> J testA(J j){//这个j和EasyGenercity<J,M,N,Y,Easy>中的J不是同一个
return j;
}
泛型的下限
泛型的下限允许指定一个类型参数可以是某个特定类或接口的任何父类或超类。这通常使用关键字super
来表达
//定义泛型的下限???
public static <A > void testAA(List<? super A> a,A p){
}
package com.easy722;
import com.easy717.EasyObject;
import java.util.*;
public class EasyGenercity<J,M,N,Y,Easy> {
//泛型 广泛的数据类型
//确保类型安全的一种途径
//定义 在类或方法上都可以定义泛型
public <E> E test(E e){
//返回的类型和传入的类型是相同的
return e;
}
//子类向父类传递 ?
//定义泛型的上限 extends
public static <J extends List> J testA(J j){//这个j和EasyGenercity<J,M,N,Y,Easy>中的J不是同一个
return j;
}
private M m;
public void test(M m,N n){//类和方法传递时:在类上声明后,在方法中直接使用
}
public static void main(String[] args) {
// testA(new ArrayList());
// testA(new HashSet());
//类型安全
List list=new ArrayList();
list.add("123");
list.add(new Object());
for(Object object:list){
//类型转换时没有明确对象的数据类型进行强制数据类型转换
//会抛出ClassCaseException(类型转换异常)
//类型不安全
//规范一个数据类型,确保类型安全
String str=(String)object;
System.out.println(str);
}
List<String> listA=new ArrayList<>();//泛型的检查在声明上 List<String>
//在编译的时候起作用
listA.add("123");
Map<String,Object> map=new HashMap<>();
List<A> list1=new ArrayList<>();
List<B> list2=new ArrayList<>();
List<C> list3=new ArrayList<>();
testAA(list1,new B());
}
//定义泛型的下限???
public static <A > void testAA(List<? super A> a,A p){
}
}
class A{}
class B extends A{}
class C extends B{}