集合
集合概念
集合只能存放对象,存放的是引用
我们平常应该用的实现类:
- List->ArrayList
- Set->HashSet
- Map->HashMap
HashSet
不可重复,指的是hashcode是否相同,而不是equals是否相同
HashSet的底层原理可以看这篇文章:https://wiki.jikexueyuan.com/project/java-collection/hashset.html
对于 HashSet 而言,它是基于 HashMap 实现的,底层采用 HashMap 来保存元素
由于 HashMap 的 put() 方法添加 key-value 对时,当新放入 HashMap 的 Entry 中 key 与集合中原有 Entry 的 key 相同(hashCode()返回值相等,通过 equals 比较也返回 true),新添加的 Entry 的 value 会将覆盖原来 Entry 的 value(HashSet 中的 value 都是
PRESENT
),但 key 不会有任何改变,因此如果向 HashSet 中添加一个已经存在的元素时,新添加的集合元素将不会被放入 HashMap中,原来的元素也不会有任何改变,这也就满足了 Set 中元素不重复的特性。
set.size();//获取集合元素个数
如果想让集合只能存相同类型的对象:使用泛型
TreeSet
TreeSet默认是排序了的
如图,如果要在TreeSet中放入自定义类型的对象,则必须实现compare方法
使用TreeSet必须放入相同类型对象
迭代器
Set set=new HashSet();
Iterator it= set.iterator();
//迭代输出法一
while(it.hasNext()){
Systems.out.printLn(it.next());//注意,调用next()会使迭代器加一
}
//迭代输出法二:foreach法(注意虽然思想是foreach,但是代码中还是只有for没有each)
for(Object obj:set){//将set中的每一个值取出来,赋值给obj
? Systems.out.printLn(obj);
}
List
List
add添加数据,addAll在指定的下标位置添加数据
Vector较老,现在基本不使用
Map
put(key,value);
https://blog.csdn.net/caisini_vc/article/details/52452498
Java中HashMap是利用“拉链法”处理HashCode的碰撞问题。在调用HashMap的put方法或get方法时,都会首先调用hashcode方法,去查找相关的key,当有冲突时,再调用equals方法。hashMap基于hasing原理,我们通过put和get方法存取对象。当我们将键值对传递给put方法时,他调用键对象的hashCode()方法来计算hashCode,然后找到bucket(哈希桶)位置来存储对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当碰撞发生了,对象将会存储在链表的下一个节点中。hashMap在每个链表节点存储键值对对象。当两个不同的键却有相同的hashCode时,他们会存储在同一个bucket位置的链表中。键对象的equals()来找到键值对。
根据key可以修改value或者移出键
-
遍历Map——法一
- map.keySet//获取map所有key的集合
- map.valueSet
通过map.KeySet来遍历:
-
遍历Map——法二
一般使用map集合,不会使用过于复杂的对象做key
工具类Collections
泛型
-
泛型类
就是C++中的模板,但是使用上会方便一点
泛型类中可以定义泛型变量 -
泛型接口
类也就因此变成了泛型类 -
泛型方法
在public之后跟上要定义的泛型,则可以在方法中的任何位置使用泛型了在静态方法中,不能使用类定义的泛型,只能使用该方法自己定义的泛型
泛型通配符
有限制的通配符可以为参数类型给出一些限制
第三个比较有用:只有实现了Comparable接口才能传入,这样方法内部就可以使用Comparable的方法而保证所有传入的对象都可以操作了
枚举
示例:
每一个枚举,都是调用了一次构造方法
使用“枚举类名.枚举”相当于调用了构造方法。但每次执行获得的都是相同对象:枚举类中的每个枚举都是单例的
这里要注意,在第一次调用枚举类时,其中所有的对象就已经被创建了!可以做一个简单的测试来证明:
enum TestEnum{
A(1,'a'),
B(2,'b'),
C(3,'c');
private final Integer number;
private final Character thisChar;
private TestEnum(Integer number,Character thisChar){
this.number=number;
this.thisChar=thisChar;
System.out.println(this.number+"is created");
}
public void showInfo(){
System.out.println(this.number+this.thisChar);
}
}
@Test
public void enumTest(){
TestEnum e=TestEnum.A;
e.showInfo();
}
输出是:
1is created
2is created
3is created
98
例如这里,调用Season.SPRING之后实际执行的是new Season("春天","春暖花开");,当然这是在