学习笔记:Java之集合框架

Java集合框架
这里写图片描述
- Collection:
- List:允许重复的有序集合,能精确控制每个元素的插入位置,可使用索引来访问List中的元素,ArrayList主要是用数组来存储元素,LinkedList主要是用链表来存储元素,当随机访问元素操作多的时候,优先使用ArrayList,当增加与删除操作多的时候,优先使用LinkedList(List允许加入null值)
- Set:存储不重复的元素
- SortedSet:继承Set接口,内部元素按照一定的规则排序(自然排序或者Comparator指定的排序规则)
- NavigableSet:是SortedSet的子接口,扩展了一些导航的方法,可以用于更精准的定位。
- HashSet:无序,实现了类Set接口,是使用对象的哈希值来决定元素的存放位置,调用对象的hashCode可以获取哈希值
- LinkedHashSet:有序,继承HashSet,使用双向链表维护元素的顺序
- TreeSet:有序,扩展自AbstractSet,并实现了NavigableSet
- Queue:先进先出的数据结构,(Queue不允许加入null值)
- Deque:继承Queue的双端队列,支持在两端插入和删除元素,可以用LinkedList实现队列(实现了Deque接口)
- PriorityQueue:继承Queue,优先队列,优先队列中元素被赋予优先级,拥有高优先级的先被删除,对内部元素的排序不会体现在遍历上
- Map:键值对映射,一个Map中不能有相同的key,每个key只能映射一个value
- SortedMap继承Map接口,key按照升序排列
- NavigableMap:是SortedMap的子接口
- HashMap:
- LinkedHashMap:继承自HashMap
- TreeMap:继承自AbstractMap,是NavigableMap的实现类

Map的遍历

  • 使用keyset
  • 使用entrySet
  • 使用forEach
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapTraverse {
    public static void main(String[] args) {
        Map<Integer,Integer> map = new HashMap<>();
        map.put(1, 2);
        map.put(3, 4);
        map.put(5, 6);
        //1、使用keyset方法
        Set<Integer> set = map.keySet();
        set.forEach(k-> System.out.println(k+","+ map.get(k)));
        //2、使用Map.Entry方法
        Set<Map.Entry<Integer, Integer>> set2 = map.entrySet();
        set2.forEach(e->System.out.println(e.getKey()+","+e.getValue()));
        //3、使用foreach方法
        map.forEach((k,v)->System.out.println(k+","+v));

    }
}

集合的遍历

  • 使用iterator接口(原始方法)
  • 使用iterator接口(新增方法)
  • 使用增强型for循环
  • 使用forEach方法
  • 使用聚合操作
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Traverse {
    public static void main(String[] args) {
        Collection<Integer> c = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            c.add(i);
            // c.add(Integer.valueOf(i));
        }
        //1、 使用Iterator原始方法,获得Iterator,初始指针为第一个元素之前
        Iterator<Integer> i = c.iterator();
        // 判断是否含有下一个元素,如果存在下一个元素,返回True,否则返回False
        while (i.hasNext()) {
            // 返回下一个元素,同时,向前移动指针位置
            Integer item = i.next();
//          System.out.println(item);
            // 在使用迭代器Iterator遍历集合元素时,如果通过集合元素修改元素,
            // 就会发生异常(ConcurrentModificationException异常)
            // c.remove(item)
            // 如果想要安全的删除元素,可以使用Iterator提供的remove方法。
            // i.remove();
        }
        //2、 使用Iterator新增的方法
        i = c.iterator();
        //i.forEachRemaining(t->System.out.println(t));
//      i.forEachRemaining(System.out::println);
        //3、使用foreach方法
        for(Integer item:c){
//          System.out.println(item);
        }
        //4、使用forEach方法遍历
//      c.forEach(System.out::println);
        //5、使用聚合操作方法
        c.stream().forEach(System.out::println);



    }

}

Iterator接口
使用Iterator接口时,在使用迭代器Iterator遍历集合元素时,如果通过集合元素修改元素,就会发生异常(ConcurrentModificationException异常),如果想要安全的删除元素,可以使用Iterator提供的remove方法。
聚合操作
流是一组元素的序列,集合对象可以通过相关方法获得流。通过集合对象的流,就可以在流的基础上对集合元素进行相关的操作,如过滤、映射、迭代等,该操作也称为流操作,也称为聚合操作。
流管道为一系列顺序的聚合操作,管道由数据源(数组、集合、IO通道等),中间操作(零个或多个)与终端操作(一个)组成。
聚合操作分为中间操作和终端操作,聚合操纵的中间操作会产生一个新的流,供后续中间操作或终端操作使用,而终端操作不会再产生流。中间操作是惰性的,这样才能在一定程度上提高性能,流只有在终端操作时才开始执行,也就是说仅仅调用流的中间操作,其实并没有真正开始流的源的遍历。一个流只能有一个终止操作,它必定是流的最后一个操作。只有调用了流的终止操作,流的源的元素才会真正的开始遍历,并且会生成一个结果返回或者产生一个副作用。中间操作分为有状态操纵和无状态操作,无状态中间操作是指元素的处理不受前面元素的影响,而有状态的中间操作必须等到所有元素处理之后才知道最终结果。并且一旦执行终端操作,则整个流都被消费掉,不可再次使用。

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/*
 *聚合操作:
 **/
public class AgOp {
    public static void main(String[] args) {
        Collection<Integer> c = new ArrayList<>();
        for (int i=0;i<10;i++){
            c.add(i);
        }
        //c.stream().filter(e->e>5).forEach(System.out::println);
        Collection<Student> c1 = new ArrayList<>();
        for (int i=0;i<10;i++){
            c1.add(new Student(i%4, "名字"+i));
        }
        //c1.stream().map(s-> new Teacher(s.getId(), s.getName())).forEach(System.out::println);
        //c1.stream().map(Student::getId).forEach(System.out::println);
        //System.out.println(c1.stream().mapToInt(Student::getId).sum());
        //c1.stream().mapToInt(Student::getId).distinct().forEach(System.out::println);
        //c1.stream().distinct().forEach(System.out::println);
        //c1.stream().distinct().sorted((s1,s2)->(Integer.valueOf(s2.getId()))
        //      .compareTo(s1.getId())).forEach(System.out::println);
        //c1.stream().mapToInt(Student::getId).distinct().peek(System.out::println).forEach(System.out::println);
//      c.stream().limit(5).forEach(System.out::println);
        //c.stream().skip(3).forEach(System.out::println);
//      System.out.println(c1.stream().mapToInt(Student::getId).max().getAsInt());
//      System.out.println(c1.stream().mapToInt(Student::getId).min().getAsInt());
//      System.out.println(c1.stream().mapToDouble(Student::getId).average().getAsDouble());
//      System.out.println(c1.stream().mapToInt(Student::getId).sum());
//      System.out.println(c1.stream().mapToInt(Student::getId).count());
//      int sum = c1.stream().mapToInt(Student::getId).reduce(Integer::sum).getAsInt();
//      System.out.println(sum);

//      int max = c1.stream().mapToInt(Student::getId).reduce(Math::max).getAsInt();
//      System.out.println(max);
//      
//      int min = c1.stream().mapToInt(Student::getId).reduce(Math::min).getAsInt();
//      System.out.println(min);
//      String jion = c1.stream().map(Student::getName).reduce(String::concat).get();
//      System.out.println(jion);
        List<Student> list = c1.stream().filter(s->s.getId()<3).collect(Collectors.toList());
        list.forEach(System.out::println);
        StringBuilder s =c1.stream().map(Student::getName)
                .collect(StringBuilder::new,StringBuilder::append,StringBuilder::append);
        System.out.println(s);

    }

}
class Teacher{
    private int id;
    private String name;
    public Teacher(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Teacher[id="+id+",name="+name+"]";
    }
}
class Student{
    private int id;
    private String name;
    public Student(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Student[id="+id+",name="+name+"]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        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 (id != other.id)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}
  • map/flatMap 映射:map操作是讲流中的元素映射成另外一种元素,接受一个Function类型的参数,是一个中间操作
  • filter 过滤:filter是对流中的元素进行过滤操作,会接受一个Predicate类型的参数,是一个中间操作。只要是不满足这个predicate的,也就是说predicate.test()返回false的元素会被过滤掉
  • distinct 去重:distinct操作是对流中的元素进行去重,是一个中间操作
  • sorted 排序:orted操作是对流中的元素按照进行排序,是一个中间操作。不带参数的是按照自然顺序进行排序。带参数的会传一个Comparator类型的参数,作为比较规则
  • limit:imit获取流中前n个元素返回。是一个中间操作。另外这个是一个短路操作(short-circuiting)。也就是说流中的元素遍历到了第n个过后,后面的元素就不在进行遍历了
  • peek:生成一个包含原Stream的所有元素的新Stream,同时会提供一个消费函数(Consumer实例),新Stream每个元素被消费的时候都会执行给定的消费函数
  • skip:skip操作是跳过流中的前n个元素。是一个中间操作
  • forEach:forEach操作是流中的元素遍历并且执行一个action。这是一个终止操作
  • toArray:将流转换为一个数组。是一个终止操作
  • reduce:reduce汇聚操作,是一个终止操作。这个方法的主要作用是把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),和前面 Stream 的第一个、第二个、第 n 个元素组合。从这个意义上说,字符串拼接、数值的 sum、min、max、average 都是特殊的 reduce
  • min、max:求最大值最小值,是一个终止操作
  • count:计算流中元素的个数。是一个终止操作
  • collect 收集:对流中元素执行一个可变汇聚操作。是一个终止操作。比如:将流中的元素放入到一个List集合当中,将流中的元素进行分组、分区,求和等等操作

聚合操作和迭代器的区别:

  • 聚合操作从流中处理数据,不改变底层的数据源,而迭代器则对集合进行操作,会改变集合
  • 聚合操作使用内部迭代的方法,而迭代器使用外部迭代进行处理
  • 聚合操作(内部迭代)可以根据需要并行处理数据,而迭代器只能顺序执行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值