Java第七章集合

目录

一、概念

二、集合体系

三、collection接口 

四、list接口及实现类

1、Arraylist

2、LinkedList

(3)Vector

五、list集合的迭代器

1、for循环

2、增强for循环

3、迭代器

六、set接口

1、HashSet

2、TreeSet

七、Map接口

1、HashMap

2、Hashtable

3、TreeMap

4、Map中的遍历方式

a:遍历方式1

b:遍历方式2

八、Collections类

九、泛型

十、Lambda表达式

十一、Stream


一、概念

数组就是容器,同一类型,创建时指定容量,长度不变,在内存空间连续存储

不足:长度固定,不能改变

需求:程序在运行时,数据数量随时会发生变化,需要的存储结构也会有特殊要求(增删多,用链表结构,查询多,用数组结构)

二、集合体系

三、collection接口 

collection(List:可重复(ArrayList、LinkedList)、Set:不可重复(HashSet、TreeSet))

collection(定义单列集合中共有的方法),Java中集合类默认使用泛型,如果没有定义集合中存储的数据类型,默认数据类型为object,建议使用泛型语法为集合指明数据类型,类型统一就不会出现转换问题

add(); 添加指定元素

clear(); 删除元素(清空)

isEmpty(); 是否为空

remove(); 删除指定元素,成功返回true,否则返回false

size(); 数组的长度

public class CollectionDemo1 {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<String>();
        c.add("a");
        c.add("b");
        System.out.println(c);//[a, b]
/*        c.clear();
        System.out.println(c);//[]*/
        System.out.println(c.contains("a"));//true
        System.out.println(c.isEmpty());//false
        System.out.println(c.remove("b"));//true
        System.out.println(c);//[a]
        System.out.println(c.size());//1
    }
}

addAll(); 添加指定集合

containsAll(); 是否包含指定集合

removeAll(); 删除指定集合

retainAll(); 两个集合共有的元素,内容改变为true,内容未改变为false

public class CollectionDemo1 {
    public static void main(String[] args) {
      Collection<String> c1  = new ArrayList<String>();
        c1.add("a");
        c1.add("b");
        c1.add("c");
        c1.add("d");
        Collection<String> c2  = new ArrayList<String>();
        c2.add("d");
        c2.add("e");
        c2.add("f");
        c1.addAll(c2);
        /*System.out.println(c1);//[a, b, c, d, d, e, f]
        System.out.println(c1.containsAll(c2));//true*/
//        System.out.println(c1.removeAll(c2));//true
        System.out.println(c1.retainAll(c2));//true
    }
}

四、list接口及实现类

list:可以存储数组

ArrayList 数组列表,查询快,中间添加,删除,效率低

LinkedList 链表利润表 ,查询慢,从头或者结尾节点开始查询,中间删除,添加效率高

Vector 数组列表,线程安全

1、Arraylist

add(E e) 向末尾添加元素

添加前先判断元素添加进去后,数组是否能放的下,如果可以,直接添加进去,如果不可以,会新创建一个数组(数组扩容)

public class ArrayListDemo1 {
    public static void main(String[] args) {
        /*
             ArrayList<String> alist = new ArrayList<String>(); 创建对象时不会创建数组,第一次添加时默认创建容量为10的数组
             ArrayList<String> alist = new ArrayList<String>(20); 创建对象时,创建一个指定容量的数组
             transient Object[] elementData;  底层存储数据的数组
             //检测容量
             public boolean add(E e) {
                ensureCapacityInternal(size + 1);
                elementData[size++] = e;
                return true;
             //添加后的长度-数组长度>0,将进行数组扩容
            if (minCapacity - elementData.length > 0)
                        grow(minCapacity);  //数组扩容
             //数组扩容的方法
            private void grow(int minCapacity) {
                int oldCapacity = elementData.length;
                int newCapacity = oldCapacity + (oldCapacity >> 1);扩容为原来的1.5倍
                if (newCapacity - minCapacity < 0)
                        newCapacity = minCapacity;
                if (newCapacity - MAX_ARRAY_SIZE > 0) 最大上限为int最大值-8   private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
                        newCapacity = hugeCapacity(minCapacity);
                elementData = Arrays.copyOf(elementData, newCapacity);
    }
    }
        */
        ArrayList<String> alist = new ArrayList<String>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("e");
        alist.add("f");
        alist.add(3,"P");
        System.out.println(alist);//[a, b, c, P, d, e, f]
    }
}
​

2、LinkedList

存储重复元素,按照顺序添加

add(E e) 向末尾添加元素

LinkedList中的方法:

public class LinkedListDemo1 {
    public static void main(String[] args) {
        /*
        * public boolean add(E e) {
            linkLast(e);
            return true;
            }
        * private static class Node<E> {  Node:节点
            E item;     数据
            Node<E> next;  后
            Node<E> prev;  前
            Node(Node<E> prev, E element, Node<E> next) {
                this.item = element;
                this.next = next;
                this.prev = prev;
        }
        *  public E get(int index) {
                checkElementIndex(index);
                return node(index).item;
            }
        * Node<E> node(int index) {
        // assert isElementIndex(index);
​
        if (index < (size >> 1)) {   索引小于数组的一半,从头节点向后找
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else { 从尾节点向前找
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }
    }
        * */
        LinkedList<String> llist = new LinkedList<>();
        llist.add("a");
        llist.add("b");
        llist.add("c");
        llist.add("d");
        llist.add("a");
        System.out.println(llist);
        System.out.println(llist.get(3));
    }
}

(3)Vector

底层也是数组实现,是线程安全的

public class VectorDome1 {
    public static void main(String[] args) {
        /*
        *   protected Object[] elementData;
        *   public synchronized boolean add(E e) {
                modCount++;
                ensureCapacityHelper(elementCount + 1);
                elementData[elementCount++] = e;
                return true;
               }
         */
        Vector<String> vector = new Vector<>();
        vector.add("a");
        vector.add("b");
        vector.add("c");
        vector.add("d");
        vector.add("a");
        System.out.println(vector);
    }
}

五、list集合的迭代器

1、for循环

支持在遍历的过程中删除集合中的元素,应注意索引的变化

public class ForDemo {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<>();
        alist.add("a");
        alist.add("a");
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("a");
        for (int i = 0; i < alist.size(); i++) {
               if (alist.get(i).equals("a")){
                alist.remove(i);
               }
        }
        System.out.println(alist);//[a, b, c]
    }
}

2、增强for循环

不支持在遍历的过程中删除集合中的元素,如果删除,会抛出java.util.ConcurrentModificationException(并发修改)异常

public class ZengqiangDemo {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<>();
        alist.add("a");
        alist.add("a");
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("a");
        for (String item:alist){
            if (item.equals("a")){
                alist.remove(item);//删除时会报错,如果使用break结束循环,可以继续执行
                break;
            }
        }
        System.out.println(alist);//[a, a, b, c, a]
    }
}

3、迭代器

调用iterator();返回一个迭代器对象

public class DiedaiqiDemo {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<>();
        alist.add("a");
        alist.add("a");
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("a");
        Iterator<String> it = alist.iterator();
        while (it.hasNext()){
            String item = it.next();
            if (item.equals("a")){
                it.remove();//删除当前指针指向的那个元素
            }
        }
        System.out.println(alist);//[b, c]
    }
}

ListIterator(集合长度),逆序输出集合中的元素,ListIterator只能遍历list接口下的集合

public class DiedaiqiDemo {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<>();
        alist.add("a");
        alist.add("a");
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("a");
        Iterator<String> it = alist.iterator();
        ListIterator<String> it =  alist.listIterator(alist.size());
        while (it.hasPrevious()){
            String item = it.previous();
            System.out.println(item);
        }
    }
}

六、set接口

不能存储重复元素,元素无序(指的是不按添加顺序排列,List集合是按照添加顺序排放),元素没有索引

set集合只能使用增强for循环和迭代器遍历(迭代器中只能使用iterator)

1、HashSet

HashSet添加元素时,如何判断元素是否存在(也就是判断HashMap的键是否重复)

add(E)在添加元素时,在里面要判断元素是否存在,需要解决两个问题:1、效率高,2、安全

add添加时,先用内容调用hashcode()方法计算出一个hash值(int类型),用哈希值比较是否相同,效率高,但是,只用hash值比较是不安全的,这时会调用equals方法对每个字符进行比较

public class Person {
    private int id;
    private String Name;
    public Person(int id, String name) {
        this.id = id;
        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) {
        Name = name;
    }
    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", Name='" + Name + '\'' +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person person = (Person) o;
        return getId() == person.getId() &&
                getName().equals(person.getName());
    }
    @Override
    public int hashCode() {
        return Objects.hash(getId(), getName());
    }
}
public class TestSetDemo {
    public static void main(String[] args) {
        HashSet<Person> hashSet = new HashSet<>();
        /*new person()在内存中会创建一个对象,有一个内存地址,public native int hashCode();*/
        Person p1 = new Person(1,"张三1");
        Person p2 = new Person(2,"张三2");
        Person p3 = new Person(3,"张三3");
        Person p4 = new Person(1,"张三1");
        Person p5 = new Person(4,"张三4");
        hashSet.add(p1);
        hashSet.add(p2);
        hashSet.add(p3);
        hashSet.add(p4);
        hashSet.add(p5);
        /*  System.out.println(hashSet);
            这块儿的结果是:[Person{id=3, Name='张三3'}, Person{id=4, Name='张三4'}, Person{id=2, Name='张三2'},
                        Person{id=1, Name='张三1'}, Person{id=1, Name='张三1'}]
          此时Person类中没有重写hasnCode()和equals(),默认调用了object中的这两个方法,取出的是内存地址*/
        System.out.println(hashSet);
        /*这块儿结果:[Person{id=1, Name='张三1'}, Person{id=2, Name='张三2'},
                    Person{id=3, Name='张三3'}, Person{id=4, Name='张三4'}]
                    因为此时重写了自己的hasnCode()和equals(),调用的是自己的这两个方法
        */
    }
}

一般的类中都重写object类中的hashcode(),重写后的计算公式都是根据对象中的包含内容的值来计算的,重写后添加时,调用自己的hashcode()

2、TreeSet

元素不重复,可以根据元素进行排列

添加时要对元素进行排序和去重,此时要实现Comparable接口

public class Car implements Comparable<Car>{
    private int num;
    private String name;
    public Car(int num, String name) {
        this.num = num;
        this.name = name;    }
​
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Car{" +
                "num=" + num +
                ", name='" + name + '\'' +
                '}';
    }
    @Override
    public int compareTo(Car o) {
        return this.num-o.num;
//        return this.name.compareTo(o.name);
    }
}
public class TestTreeSetDemo {
    public static void main(String[] args) {
        TreeSet<Car> treeSet = new TreeSet<>();
        Car car1 = new Car(1,"宝马1");
        Car car2 = new Car(2,"宝马2");
        Car car3 = new Car(3,"宝马3");
        Car car4 = new Car(4,"宝马4");
        Car car5 = new Car(1,"宝马5");
        treeSet.add(car1);
        treeSet.add(car2);
        treeSet.add(car3);
        treeSet.add(car4);
        treeSet.add(car5);
        /*System.out.println(treeSet);
        没有实现Comparable之前
        会报错,ava.lang.ClassCastException(转型异常):day3.treesetdemo.Car cannot be cast to java.lang.Comparable
          所以要实现Comparable接口
        */
        System.out.println(treeSet);
        /*
        按num进行排序
          public int compareTo(Car o) {
        return this.num-o.num;
        }
        [Car{num=1, name='宝马1'}, Car{num=2, name='宝马2'}, Car{num=3, name='宝马3'}, Car{num=4, name='宝马4'}]
         */
        /*
        按name进行排序
            public int compareTo(Car o) {
                return this.name.compareTo(o.name);
                }
         [Car{num=1, name='宝马1'}, Car{num=2, name='宝马2'}, Car{num=3, name='宝马3'},
         Car{num=4, name='宝马4'}, Car{num=1, name='宝马5'}]
         */
    }
}
​

七、Map接口

双列存储,键---值,键不允许重复,值可以重复

所实现的类:HashMap TreeMap Hashtable

1、HashMap

public class MapDemo1 {
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        map.put("a","aaa");    //向map中添加元素
        map.put("b","bbb");
        map.put("c","ccc");
        map.put("d","ddd");
        System.out.println(map);//System.out.println(map);
        /*containsKey()   是否包含指定的键*/
        System.out.println(map.containsKey("b"));//true
        /*containsValue   是否包含指定的值*/
        System.out.println(map.containsValue("ccc"));//true
        /*get()    根据指定的键找到对应的值*/
        System.out.println(map.get("b"));///bbb
        /*remove()   删除指定的键并返回对应的值*/
        System.out.println(map.remove("d"));//ddd
        /*size()   有几组键值对*/
        System.out.println(map.size());//3
        /*获取map中键的那一列,存放到一个set中*/
        Set<String> set = map.keySet();
        System.out.println(set);//[a, b, c]
        /*获取map中值的那一列,存放到一个collection中*/
        Collection<String> val = map.values();
        System.out.println(val);//[aaa, bbb, ccc]
    }
}
​

put(K,V)向HashMap中添加数据过程及底层结构:
    putVal(hash(key),key,value,false,true)
    哈希函数根据内容的哈希值计算在哈希表中的位置:(h = key.hashCode()) ^ (h >>> 16)
    第一次添加元素时,会创建哈希表,将元素插入到对应的位置,后面如果有位置相同的元素就放在链表中
    当链长度大于等于7时,就会将链表转为红黑树
    哈希表默认长度是:DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
    最大容量是:MAXIMUM_CAPACITY = 1 << 30
    负载因子:DEFAULT_LOAD_FACTOR = 0.75f
    当哈希容量到达整个数组的的0.75倍是,进行扩容,扩容为原来的2倍

2、Hashtable

不允许有为null的key,是线程安全的,添加了同步锁,锁住了整个put(),访问量较小时可以使用,访问很高时,效率太低,后面会有新的线程安全来代替

3、TreeMap

可以根据键的自然顺序排序(a,b,c.............;1,2,3,.........),key值所在的类必须实现comparable接口

4、Map中的遍历方式

a:遍历方式1

public class MapDemo3 {
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        map.put("c","ccc");
        map.put("a","aaa");
        map.put("b","bbb");
        map.put("d","ddd");
        Set<String> keyset = map.keySet();
        for (String key:keyset){
            System.out.println(map.get(key));
        }
    }
}

b:遍历方式2

.entrySet():把Map中的键值对封装在一个Entry对象中,将多个Entry对象装进Set集合中,Entry对象包含键值

public class MapDemo3 {
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        map.put("c","ccc");
        map.put("a","aaa");
        map.put("b","bbb");
        map.put("d","ddd");
        Set<Map.Entry<String,String>> entrySet = map.entrySet();
        for (Map.Entry entry:entrySet){
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
    }
}

八、Collections类

Collections是集合类的工具类

其中常用的方法:

addAl l(Col lection<? super T> c, T... elements);

binarySearch(List<? extends Comparable<? super T>> l ist, T key)

sort(List<T> l ist)

sort(List<T> l ist, Comparator<? super T> c)

swap(List<?> l ist, int i, int j)

copy(List<? super T> dest, List<? extends T> src) ; 注意 dest size需大于等于src.size

emptyList() 返回为空的集合,不能添加数据

fi l l(List<? super T> l ist, T obj)

max(Col lection<? extends T> col l)

min(Col lection<? extends T> col l)

replaceAl l(List<T> l ist, T oldVal, T newVal)

reverse(List<?> l ist)

public class CollectionsDemo {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        Collections.addAll(list,2,1,3,4,5);
        System.out.println(list);//[2, 1, 3, 4, 5]
        Collections.sort(list);
        System.out.println(list);//[1, 2, 3, 4, 5]
        System.out.println(Collections.binarySearch(list,4));//3
        Collections.swap(list,1,3);
        System.out.println(list);//[1, 4, 3, 2, 5]
        /*emptyList(),返回一个空集合,此集合不能使用,避免在判断时出现空指针
        * List<Integer> list1 = Collections.emptyList();
          list1.add(1);
          System.out.println(list1);
        * */
//        Collections.fill(list,8);
//        System.out.println(list);//[8, 8, 8, 8, 8]
        System.out.println(Collections.max(list));//5
        System.out.println(Collections.min(list));//
        Collections.replaceAll(list,2,6);
        System.out.println(list);//[1, 4, 3, 6, 5]
        Collections.reverse(list);
        System.out.println(list);//[5, 6, 3, 4, 1]
        List<Integer> list1 = new ArrayList<>();
        list1.add(9);
        list1.add(8);
        list1.add(7);
        Collections.copy(list,list1);
        System.out.println(list);//[9, 8, 7, 4, 1]
    }
}

T... elements,定义可变长度的参数,本质是数组,一个参数列表中只能有一个,并且放在参数列表的最后一位

九、泛型

把类型作为参数传进去,参数化类型或者类型参数化

不明确类型默认为object类型,向上转为object类型,在需要时向下转型,会出现转型异常,java中希望集合存储同一类型数据,使用泛型语法,在创建时,把类型当做参数传进去,这样集合中的类型就明确

子类和父类都是泛型类,创建子类对象时传入类型,父类类型与子类类型一致,如果子类不是泛型类,那么明确父类类型,因为子类如果不是泛型类,创建子类对象时不能传入类型,父类类型也就无法明确

类型通配符 ?

<? extends T> 泛型的类型上限,只能传入类型以及类型的子类

<? super T> 泛型的类型下限,只能传入类型以及类型的父类

public class DemoB<T> {
     /*
        ?类型通配符(任意的), 用来定义表示实际参数的类型
      */
    /* public void test(DemoB<?> db){    
     }
     public static void main(String[] args) {
         
         DemoB<Integer> di = new DemoB<>();
         DemoB<Number> dn = new DemoB<>();
         
         di.test(di);
         dn.test(dn);
    }*/ 
     // <?  extends 类型>  泛型类型上限     只能传入 类型以及类型的子类
     /*public void test(DemoB<? extends Number> db){
            
     }
     public static void main(String[] args) {
         
         DemoB<Integer> di = new DemoB<>();
         DemoB<Number> dn = new DemoB<>();
         
         di.test(di);
         dn.test(dn);
    }*/  
     //<? super Number> 类型下限    只能传入Number类型 以及 Number的父类
     public void test(DemoB<? super Number> db){
            
     }
     public static void main(String[] args) {
         
         DemoB<Object> di = new DemoB<>();
         DemoB<Number> dn = new DemoB<>();
         
         di.test(di);
         dn.test(dn);
    }
       
}
​

类型擦除:泛型是JDK1.5之后的语法,以前的版本还不支持,所以底层还是使用Object作为类型,泛型的主要作用是在编译期间对类型进行明确的

public class DemoC {
    
     public static void main(String[] args) throws NoSuchFieldException, SecurityException {
         ArrayList<String> list =  new ArrayList<>();
         
              Class c = list.getClass();
              Field f = c.getDeclaredField("elementData");
              System.out.println(f.getName()+"::"+f.getType());
    }

十、Lambda表达式

Lambda 表达式是一个匿名函数,我们可以把 lambda 表达式理解为一段可以传递的代码(将代码段像数据一样传递)。使用它可以写出更简洁, 更灵活的代码。作为一种更紧凑的代码风格,使 java 语言的表达式能力得到的提升。

Lambda 表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此可以使用更少的代码来实现同样的功能。

创建conparator接口的匿名内部类对象,在匿名内部类对象重写compare方法,进行比较,匿名内部类也是一种语法的简化,Lambda 表达式又对匿名内部类语法进行简化,直接将接口中的方法实现作为参数传递

Lambda 表达式又称为函数式编程

public class Demo {
​
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
                     list.add("b");
                     list.add("a");
                     list.add("c");
                     list.add("d");
        /*list.sort(new Comparator<String>() {
                      @Override
                      public int compare(String o1, String o2) {
                          return 0;
                      }
                  });*/
/*结构:  (参数列表)->{方法体}*/        
        
           list.sort( (o1,o2)->{ return o1.compareTo(o2); } );
        //(o1,o2)->{ return o1.compareTo(o2); } 匿名函数
    }
}
​
无参数,无返回值,lambda 体中只有一行代码时,{}可以忽略 
() -> System.out.println("Hello World"); 
无参数,有返回值 
() -> { return 3.1415 }; 
有参数,无返回值 
(String s) -> { System.out.println(s); } 
有一个参数,无返回值 
s -> { System.out.println(s); } 
有多个参数,有返回值 
(int a, int b) -> { return a + b; } 
有多个参数,表达式参数类型可以不写,jvm 可以根据上下文进行类型推断 
(a, b) -> { return a - b; }

在Lambda 表达式中 ,只能有一个抽象方法,如果有两个,编译会报错,使用@FunctionalInterface修饰的接口就是功能函数接口

@FunctionalInterface
public interface LambdaDemo {
​
       //void test();
​
      //void test1(int a,int b);
​
       int test2(int a,int b);
​
}
public class TestLambda {
​
    public static void main(String[] args) {
        //LambdaDemo lam =  ()->System.out.println("hello");
       /* LambdaDemo lam =  (int a,int b)->{ System.out.println(a+b); };
                   lam.test1(10,5);*/
        LambdaDemo lam =   (a,b)->{
                                    System.out.println("");
                                    return a+b;
                                };
                 int res =    lam.test2(10,6);
                 System.out.println(res);
                /* new Thread(new Runnable(){
                     @Override
                     public void run() {
                     }
                 });*/
                /*new Thread(()->{
                    System.out.println("qqqqq");
                });*/
       /* JButton jb = new JButton("");
                 jb.addActionListener((e)->{
                 });*/
        ArrayList<String> list = new ArrayList<>();
        list.add("b");
        list.add("a");
        list.add("c");
        list.add("d");
         /*list.forEach(new Consumer<String>(){
             @Override
             public void accept(String o) {
                 System.out.println(o);
             }
         });*/
        list.forEach( (e)->{ System.out.println(e);} );
    }
}

十一、Stream

集合和数组中的操作有些简单,java8提供了Stream来丰富结合和数组操作,分为两步

(1)获取流

集合.stream() Arrays.stream(a); Stream.of(1,2,3,4,5,6,7); 字符流中reader.lines(); 可以将读入到程序中字符存入到Stream中

(2)流操作

中间操作 返回的还是Stream 过滤,排序,去重.... 终端操作 获取到你最终想要的数据 toList, toSet, max min

public static void main(String[] args) {
       /* int [] a = {1,2,3,6,4,5};
        Arrays.stream(a);*/
        Stream.of(1,2,3,4,5,6,7);
        ArrayList<Integer> alist = new ArrayList<>();
                           alist.add(2);
                           alist.add(1);
                           alist.add(5);
                           alist.add(3);
                           alist.add(6);
                           alist.add(4);
                           alist.add(6);
                           alist.add(7);
         /*alist.stream()
                .filter( (e)->{return e>=5;} )
                .forEach((s)->{  System.out.println(s); });*/
       /* alist.stream()
                .distinct()
                .forEach((s)->{  System.out.println(s); });
*/
        alist.stream()
                 .distinct()
                 .sorted((a,b)->{return a-b;})
                 .skip(6)
                 .limit(2)
​
                .forEach((s)->{  System.out.println(s); });
        //1,2,3,4,5,6,7
    }
Stream与IO流是完全不同的, Stream提供了对集合元素更加丰富的操作(中间操作,终端操作).
public class StreamDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
                     list.add("b");
                     list.add("a");
                     list.add("c");
                     list.add("d");
             /*
               要找出集合中c字符,遍历集合
               for(String s : list){
                  if(s.equals("c")){
                  }
               }
              */
        // 把集合或数组中的元素添加到Stream对象中去.
        Stream<String> stream = list.stream();
        List<String> list1 =  stream.filter( (e)->{ return e.equals("c"); }) //中间操作
                                     .collect(Collectors.toList()); //终端操作
        System.out.println(list1);//[c]
        System.out.println(list);//[b, a, c, d] 流操作不影响原始集合数据
​
​
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值