Java集合
========
集合树关系
介绍:
1》Collection下有Set(无序不可重复)、queue(队列&桟)、List(有个加入时的先后顺序,so可重复)
2》Map下(键值对)可以理解为一种关联
Collection
========
三种遍历方法
class People{
private String name = "jim";
//这里复写Object的toString方法,为的是在遍历的时候打印出“People<name>: jim”讯息
@Override
public String toString() {
// TODO Auto-generated method stub
return "People<name>: "+name;
}
}
class Test {
public static void main(String[] args) {
//新建一个books coolection类型的集合
Collection books = new ArrayList<>();
//添加元素,可以看到并没有对添加的
//类型多加限制(String、int、people对象)
books.add("1");
books.add(123);
books.add(new People());
//遍历方法一:使用外部的迭代器
Iterator iterator = books.iterator();
while(iterator.hasNext()){
//注意:如遍历到People,iterator.next()返回的是Object类型,
//由于new的是一个People对象,当调用Object的toString方法时候,
//最终会调用在People中复写好的toString方法,
//最终会打印出“People<name>: jim”讯息
System.out.println(iterator.next());
}
//遍历方法二:java5 提供的forEach方法
for (Object object : books) {
System.out.println(object);
}
//遍历方法三:内置的迭代器方法,
//java8 在Iterable(collection的父类,so这里的books可以直接调用)
//新增的2个方法:forEachRemaining & forEach括号内为lambda表达式,
//可以理解像方法二中的forEach一样返回的是一个Object对象,然后用括号
//内的lambda表达式来接收,返回的Object对象,并对其进行处理
//forEachRemaining & forEach括号内需要的参数是一个Comsumer类型
//的函数式接口所以可以用lambda表达式来实现传参
books.forEachRemaining(obj->System.out.println(obj));
books.forEach(obj->System.out.println(obj));
}
}
//程序结果:
1
123
People<name>: jim
注意:迭代器使用的是快速失败(fail-fast)机制,在使用迭代器遍历collection时,此时,如果集合的元素发生了变化,会立即报ConeurrntModificationException异常,我们最好在遍历的时候保证集合的不可修改性;
-
java8新增Predicate(谓语)操作集合,例子
books.removeIf(ele->((String)ele).length()< 10)
可以看见括号里是一个Predicate类型的函数式接口,现在这里使用lambda表达式代替
这里的“谓语”的理解:一个if括号中的判断条件(Predicate类型);
-
还有一种“流”式的集合,例子:
IntStreamis = IntStream.builder()
.add(10)
.add(-12)
.add(20)
.build();
理解为一种集合,集合中的数据都保存在一段字节/字符流中;
Set集合
========
Set集合:可以理解为是一个罐子,所有元素都”扔“在里面,so因为是”扔“没有顺序,不能重复,重复之后不知道两个相同的要怎么取出来。
Set集合的元素的值可以是null
hashSet集合:调用对象的hashcode()方法得到hashCode值决定在内存中的存储位置
hashSet集合:两个对象调用equals()方法返回true,但hashCode值不一样,会形成一种结果,两个值一样的东西因为hashCode值不一样分别存储进了Set集合,这违背了Set的初衷,so,需要保持equals()& hashCode() 方法返回的结果一致
hashSet:因为是根据hashCode值决定存储位置,因为会根据他的hash值计算出存储位置,so,随机访问性能较优
LinkedHashSet:较hashSet多了一个链表指针,so,可以维护一个添加顺序,也因此效率低于HashSet,注意这是多出来的部分,其他还和hashSet一样
TreeSet:依据红黑树来维持元素顺序,有自然排序&定制排序两种。
TreeSet:如果希望其能正常运作,只能添加一种类型的对象,
-
自然排序:通过对象里复写好的compareTo()去实现排序
定制排序:在newTreeSet()传入一个lambda表达式(comparator函数式接口内置compare(To1, T o2))
可以理解:自然排序和定制排序并没有多大区别,一个在类中实现了compare(),一个则是将compare()作为参数在new的时候传入
注意:通过compare()的返回值为-1、0、1;来决定To1 To2的大小
List集合
========
基础属性介绍:有顺序so可以输入重复的数据元素,它判断两个对象相等只要equals()相等即可
比较Set它多了一个自己的ListIterator()方法,比较原始的Iterator()多了一个前向迭代的功能
ArrayList:依靠数组实现,封装了一个动态的允许再分配的Object[]数组
Queue集合
========
ArrayDeque和LinkedList既可以作桟使用也可以作队列使用
Map集合
========
Map存储的是key-value,是一种关联关系,可以凭借key找到value
其实Map可以理解为包装的很好的Set,key即为Set集合的元素,无序且不可重复,而value则是和key绑定在一起的东西
至于HashMap、LinkedHashMap、TreeMap可根据之前说的Set类推,只不过集合中的操作元素是Key而不是Value
Collections工具类
========
-
主要有四个功能:
1》对已有集合的排序操作
2》对已有集合的查找、替换
3》帮已有集合生成一种只读副本
4》将已有集合变成线程安全
具体功能对应的函数可在用到时在自行搜索