Java之集合(最全集合相关知识)

集合

集合

一、集合概述

1、为什么要学习集合?

数组可以储存多个对象,但在无法确定需要保存多少个对象时,数组将不再适用,因为数组的长度不可变。
所以为了保存这些数目不确定的对象,Java中提供了集合,集合可以存储任意类型的对象,并且长度可变。

2、定义

Java中的集合就像一个容器,专门用来存储Java对象。

3、说明

集合对象可以是任意的数据类型,并且长度可变

4、注意

这些集合类都位于java.util包中

5、集合分类

5.1 单列集合Collection

(1)单列集合根接口,用于存储一系列符合某种规则的元素
(2)Collection集合有两个重要的子接口,分别是List和Set
(3)List集合的特点是元素有序、可重复。该接口的主要实现类有ArrayList和LinkedList
(4)Set集合的特点是元素无序并且不可重复。该接口的主要实现类有HashSet和TreeSet

5.2 双列集合Map

(1)双列集合根接口,用于存储具有键(key)、值(Value)映射关系的元素
(2)Map集合中每个元素都包含一对键值,并且Key唯一,在使用Map集合时通过指定的Key找到对应的Value
(3)Map接口的主要实现类有HashMap和TreeMap

二、Collection接口

1、相关方法

boolean add(Object o) 向集合中添加一个元素
boolean addAll(Collection c) 将指定集合c中的所有元素添加到该集合中
void clear() 删除该集合中的所有元素
boolean remove(Object o) 删除该集合中指定的元素
boolean removeAll(Collection c) 删除该集合中包含指定集合c中的所有元素
boolean isEmpty() 判断该集合中是否为空
boolean contains(Object o) 判断该集合中是否包含某个元素
boolean containsAll(Collection c) 判断该集合中是否包含指定集合c中的所有元素
int size() 获取该集合元素个数
Iterator iterator 返回在该集合的元素上进行迭代的迭代器(Iterator),用于遍历该集合所有元素
Stream stream() 将集合源转换为有序元素的流对象(JDK 8新方法)

泛型:指的是集合中存储元素的数据类型

public class Demo1{
    public static void main(String[] args){
        //创建集合对象
        Collection<String> list = new ArrayList<String>();

        //boolean add(Object o)             向集合中添加一个元素
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        System.out.println(list);

        //int size()                        获取该集合元素个数
        int size = list.size();
        System.out.println(size);

        //boolean isEmpty()                 判断该集合中是否为空
        boolean flag = list.isEmpty();
        System.out.println(flag);

        //boolean contains(Object o)        判断该集合中是否包含某个元素
        flag = list.contains("eee");
        System.out.println(flag);

        //boolean remove(Object o)          删除该集合中指定的元素
        boolean b = list.remove("bbb");
        System.out.println(b);
        System.out.println(list);

        //boolean removeAll(Collection c)   删除该集合中包含指定集合c中的所有元素
        Collection<String> list3 = new ArrayList<String>();
        list3.add("aaa");
        list3.add("ccc");

        //boolean containsAll(Collection c) 判断该集合中是否包含指定集合c中的所有元素
        boolean flag = list.containsAll(list3);
        System.out.println(flag);

        //将list集合中包含list3集合所有的元素都删除
        list.removeAll(list3);
         System.out.println(list);

        //boolean addAll(Collection c)      将指定集合c中的所有元素添加到该集合中
        Collection<String> list2 = new ArrayList<String>();
        list2.addAll(list);
        System.out.println(list2);

        //void clear()                      删除该集合中的所有元素
        list2.clear();
        System.out.println(list2);
    }
}


三、List接口

1、List接口简介

1.1 定义

List接口继承自Collection接口,是单列集合的一个重要分支,习惯性的会将实现了List接口的对象称为List集合

1.2 特点

(1)List集合中允许出现重复元素,所有元素是以一种线性方式进行存储的,在程序中可以通过索引(类似于数组中的元素角标)来访问集合中的元素。
(2)List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致

1.3 List集合常用方法

void add(int index,Object element) 将元素element插入在List集合的指定索引位置
boolean addAll(int index,Collection c) 将集合c包含的所有元素插入到List集合的指定索引位置
Object get(int index) 返回集合索引index处的元素
Object remove(int index) 删除index索引处的元素
Object set(int index,Object element) 将索引index处元素替换成element元素,并将替换后的元素返回
int indexOf(Object o) 返回对象o在List集合中首次出现的位置索引
int lastIndexOf(Object o) 返回对象o在List集合中最后一次出现的位置索引
List subList(int fromIndex,int toIndex) 返回从索引fromIndex(包括)到toIndex(不包括)处所有元素集合组成的子集合
Object[] toArray() 将集合元素转换成数组
default void sort(Comparator<? super E>c) 根据指定的比较器规则对集合元素排序

1.4 相关代码
public class Demo2{
    public static void main(String[] args){
        //创建集合对象
        List<String> list = new ArrayList<String>();
        list.add("aaa");
        list.add("bbb");

        //void add(int index,Object element) 将元素element插入在List集合的指定索引位置
        list.add(1,"ccc");
        
        System.out.println(list)  //[aaa,ccc,bbb]
        
        //Object get(int index)  返回集合索引index处的元素
        String str = list.get(0);
        System.out.println(str); 

        //Object remove(int index)    删除index索引处的元素
        String del = list.remove(0);
        System.out.println(del);
        System.out.println(list);

        //Object set(int index,Object element)将索引index处元素替换成element元素,并将替换后的元素返回
        String old = list.set(1,"ddd");
        System.out.println(old);
        System.out.println(list);

        //int indexOf(Object o)   返回对象o在List集合中首次出现的位置索引
        int index = list.indexOf("ddd");
        System.out.println(index);

        //int lastIndexOf(Object o)   返回对象o在List集合中最后一次出现的位置索引
        list.add("ddd");
        System.out.println(list);
        index = list.lastIndexOf("ddd");
        System.out.println(index);

        System.out.println("=============================================");
        //List subList(int fromIndex,int toIndex)  返回从索引fromIndex(包括)到toIndex(不包括)处所有元素集合组成的子集合
        List<string> list2 = list.subList(1,list.size()-1);
        System.out.println(list2);

        //Object[] toArray()    将集合元素转换成数组
        Object[] arr = list.toArray();
        for(int i=0;i<arr.length;i++)
        {
            System.out.println(arr[i]);
        }

        //boolean addAll(int index,Collection c)   将集合c包含的所有元素插入到List集合的指定索引位置
        List<String> list2 = new ArrayList<String>();
        list2.add("aaa");
        list2.add("eee");
        list2.addAll(1,list);
        //list2:[aaa,aaa,bbb,ccc,eee]
        System.out.println(list2)  



    }
}



四、ArrayList集合

1、说明

ArrayList是List接口的一个实现类,它是程序中最常见的一种集合
ArrayList内部的数据存储结构是数组形式

2、特点

(1)由于ArrayList的存储结构,在增加或删除指定位置的元素时,会创建新的数组,效率比较低,因此不适合做大量的真删操作。
(2)这种数组结构允许程序通过索引的方式来访问元素,使用ArrayList集合在遍历和查找元素时显得非常高效。

3、优缺点

底层是数组实现的。查询快、增删慢。

4、相关代码

public class Demo03{
    public static void main(String[] args){
        //创建ArrayList集合对象
        ArrayList<String> list = new ArrayList<String>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");

        //获取集合长度
        int size = list.size();
        System.out.println("集合的长度是"+size);

        //获取元素
        System.out.println(list);          //[aaa,bbb,ccc,ddd]

        System.out.println(list.get(0));    //aaa
        System.out.println(list.get(1));    //bbb
    }
}


五、LinkedList集合

1、说明

LinkedList是List接口的另一个实现类
LinkedList内部包含有两个Node类型的first和last属性的双向循环链表结构。

2、特点

由于LinkedList的存储结构,
LinkedList集合对于元素的遍历和查找效率较低。
LinkedList集合对于元素的增删操作表现出很高的效率。

3、优缺点

底层是链表实现的。增删快、查询慢

4、相关代码

public class Demo4{
    public static void main(String[] args){
        //创建LinkedList集合对象
        LinkedList<String> list = new LinkedList<String>();
        list.add("aaa");
        list.add("bbb");

        System.out.println(list);  //[aaa,bbb]

        //one
        list.addFirst("ttt");
        //或者
        //two
        list.add(0,"ttt");

        System.out.println(list);   //[ttt,aaa,bbb]


    }
}


六、Iterator遍历集合

1、定义

Iterator接口是java集合框架中的一员,主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。
同时也用于遍历单列集合

2、示例

Iterator iterator = list.iterator();
while(iterator.hasNext()){
    Object obj = iterator.next();  //取出ArrayList集合中的元素
    System.out.println(obj);
}

3、成员方法

boolean hasNext(); 判断迭代器中是否还有下一个元素
E next(); 获取迭代器中下一个元素
void remove(); 从迭代器中删除某个元素

//示例一
public class Demo5{
    public static void main(String[] args){
        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");
        
        //使用迭代器对集合进行遍历
        //获取迭代器对象,同时将指针向后移动一位
        Iterator<String> it = coll.iterator();

        
        //boolean hasNext();    判断迭代器中是否还有下一个元素
        boolean b = it.hasNext();
        System.out.println(b);
        
        //E next();              获取迭代器中下一个元素
        String e = it.next();
        System.out.println(e);   //aaa
         
        b = it.hasNext();
        System.out.println(b);
        e = it.next();
        System.out.println(e);  //bbb

        b = it.hasNext();
        System.out.println(b);
        e = it.next();
        System.out.println(e);  //ccc
       .....

        //或者
        while(it.hasNext()){
            String e = it.next();
            System.out.println(e);
        }

    }
}


//示例二
public class Demo6{
    public static void main(String[] args){
        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");
        
        //使用迭代器对集合进行遍历
        //获取迭代器对象,同时将指针向后移动一位
        Iterator<String> it = coll.iterator();

        while(it.hasNext()){
            String e = it.next();
            System.out.println(e);
        }

    }
}

//示例三
public class Demo7{
    public static void main(String[] args){
        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");
        
        //使用迭代器对集合进行遍历
        //获取迭代器对象,同时将指针向后移动一位
        Iterator<String> it = coll.iterator();

        //使用迭代器进行删除元素
        while(it.hasNext()){
            String e = it.next();
            if(e.equals("bbb")){
               it.remove();   //推荐的删除方式
            }
        }
        System.out.println(coll); 

    }
}


七、foreach遍历集合

1、定义

foreach循环是一种更加简洁的for循环,也称增强for循环,用于遍历数组或集合中的元素

2、语法

for(容器中元素类型 临时变量 : 容器变量){
//执行语句
}

3、示例

for(Object obj : list){
System.out.println(obj);
}

4、更通俗一点的格式

for(数据类型 变量名 : 容器对象名称){
循环体语句;
}

5、示例代码

public class Demo8{
    public static void main(String[] args){
        //使用增强for循环遍历数组
        String[] arr = {"张三","里斯","王五"};
        for(String s : arr){
            System.out.println(s);
        }

        //使用增强for循环遍历集合
        Collection<Integer> coll = new ArrayList<Integer>();
        coll.add(100);
        coll.add(200);
        coll.add(300);
        coll.add(400);

        for(Integer i : coll){
            System.out.println(i);
        }
    }
}

6、JDK8版本后的forEach()方法遍历集合

6.1 定义

forEach方法是JDK8中新增的遍历集合元素的方法,根据Lambda表达式特性,该方法所需要的参数是一个函数式接口。
list.forEach(obj->System.out.println(“迭代器集合元素:” + obj));

同时针对迭代器对象也提供了一个forEachRemaining方法来进行遍历。该方法同样需要一个函数式接口。
Iterator it = list.iterator();
it.forEachRemaining(obj->System.out.println(“迭代器元素:” + obj));

public class Demo9{
    public static void main(String[] args){
        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");
        
        coll.forEach((String e)->{System.out.println(e);});
        
        //JDK8版本后的迭代器对象forEach()方法遍历集合
        Iterator<String> it = coll.iterator();
        it.forEachRemaining((String e)->{System.out.println(e);});

    }
}

八、Set接口简介

1、说明

Set接口和List接口一样,同样继承自Collection接口。

2、特点

Set接口中的元素无序,并且都会以某种规则保证存入的元素不出现重复。

3、种类

HashSet
TreeSet

九、HashSet集合

1、说明

HashSet是Set接口的一个实现类,它所存储的元素不可重复,并且无序。

2、特点

当向HashSet集合中添加一个元素时,首先会调用该元素的hashCode()方法来确定元素的存储位置,然后再调用元素对象的equals()方法来确保该位置没有重复元素。

HashSet set = new HashSet();
set.add("Jack");
set.add("Eve");
...
set.forEach(o->System.out.println(o));

3、优缺点

无索引、不能存储重复元素、存储无序。

public class Demo10{
    public static void main(String[] args){
        //创建HashSet集合对象
        HashSet<String> hs = new HashSet<String>();
        hs.add("hello");
        hs.add("world");
        hs.add("java");

        System.out.println(hs);  //[world,java,hello]

    }
}

4、注意

在对对象进行处理时,可以在model层利用系统的快捷键创建hascode+equals方法,来去重。

十、TreeSet集合

1、说明

TreeSet是Set接口的另一个实现类,它内部采用平衡二叉树来存储元素,来保证TreeSet集合中没有重复的元素,并且可以对元素进行排序。

2、定义

二叉树就是每个节点最多有两个子节点的有序树,每个节点及其子节点组成的树称为子树,左侧的节点称为"左子树",右侧的节点称为"右子树",其中左子树上的元素小于它的根结点,而右子树上的元素大于它的根结点。

3、存储原理

TreeSet集合没有元素时,新增的第1个元素会在二叉树最顶层;
接着新增元素时,首先会与根结点元素比较;
如果小于根节点元素就与左边的分支比较;
如果大于根节点元素就与右边的分支比较;
以此类推

4、优缺点

底层是二叉树实现。可以进行元素的排序

public class Demo11{
    public static void main(String[] args){
        TreeSet<Integer> ts = new TreeSet<Integer>();
        ts.add(12);
        ts.add(8);
        ts.add(15);
        ts.add(13);

        System.out.println(ts);   //[8,12,13,15]
    }
}

5、相关方法

Object first() 返回TreeSet集合的首个元素
Object last() 返回TreeSet集合的最后一个元素
Object lower(Object o) 返回TreeSet集合中小于给定元素的最大元素,如果没有返回null
Object floor(Object o) 返回TreeSet集合中小于或等于给定元素的最大元素,如果没有返回null
Object higher(Object o) 返回TreeSet集合中大于给定元素的最小元素,如果没有返回null
Object ceiling(Object o) 返回TreeSet集合中大于或等于给定元素的最小元素,如果没有返回null
Object pollFirst() 移除并返回集合的第一个元素
Object pollLast() 移除并返回集合的最后一个元素

6、TreeSet如何保证排序?

向TreeSet集合添加元素时,都会调用compareTo()方法进行比较排序,该方法是Comparable接口中定义的,因此要想对集合中的元素进行排序,就必须实现Comparable接口。
Java中大部分的类都实现了Comparable接口,并默认实现了接口中的CompareTo()方法,如Integer、Double和String等。

7、排序种类

7.1 自然排序

要求存储的元素类必须实现Comparable接口,并重写compareTo()方法。

public class Person implements Comparable<Person>{
    private String name;
    private int age;
    public Person(){
        super();
    } 
    
    public Person(String name,int age)
    {
        super();
        this.name = name;
        this.age = age;
    }

    ......//get/set方法

    @Override
    public int compareTo(Person p){
        //按照年龄的降序排列
        int result = p.age-this.age;
        return result;
    }

    .....//toString方法
}


7.2 定制排序

要求自定义一个比较器,该比较器必须实现Comparator接口,并重写compare()方法,然后将该比较器作为参数传入集合的有参构造。

public class Demo12{
    public static void main(String[] args){
        TreeSet<Teacher> ts = new TreeSet<Teacher>(new Comparator<Teacher>() {
            @Override
            public int compare(Teacher t1,Teacher t2){
                int result = t1.getAge() - t2.getAge();
                return result;
            }
        });
    } 
}

Teacher t1 = new Teacher("张三",23);
Teacher t2 = new Teacher("里斯",24);
Teacher t3 = new Teacher("王五",25);

ts.add(t1);
ts.add(t2);
ts.add(t3);


十一、Map接口简介

1、说明

Map接口是一种双列集合,它的每个元素都包含一个键对象key和值对象Value,键和值对象之间存在一种对应关系,称为映射。

2、特点

Map中的映射关系是一对一的,一个键对象Key对应唯一一个值对象Value,其中键对象Key和值对象Value可以是任意数据类型,并且键对象Key不允许重复,这样在访问Map集合中的元素时,只要指定了Key,就能找到对应的Value。

十二、HashMap集合

1、说明

HashMap集合是Map接口的一个实现类,它用于存储键值映射关系,该集合的键和值允许为空,但键不能重复,且集合中的元素是无序的。

2、特点

HashMap底层是由哈希表结构组成的,其实就是"数组+链表"的组合体,数组是HashMap的主体结构,链表则主要是为了解决哈希值冲突而存在的分支结构。正因为这样特殊的存储结构。HashMap集合对于元素的增、删、改、查操作表现出的效率都比较高。

3、HashMap相关方法

3.1 HashMap集合存储元素的原理

依赖hashCode()方法计算哈希值,通过哈希值找到存储位置。
如果哈希值计算重复,则比较equals()方法,来比较键的内容是否相同。
如果equals方法返回的是true,会使用新值将老值替换。并且返回老值。
如果equals方法返回false,将后添加的元素放在之前元素的下列。

水平:数组结构
竖直:链表结构

3.2 相关代码

T put(Object key, Object value) //向Map集合中添加指定键值映射的元素
int size() //返回Map集合键值对映射的个数
Object get(Object key) //返回指定键所映射的值,如果此映射不包含该键的映射关系,则返回null
boolean containsKey(Object key) //查看Map 集合中是否存在指定的键对象key
boolean containsValue(Object value) //查看Map 集合中是否存在指定的值对象value
Object remove(Object key) //删除并返回Map 集合中指定键对象key 的键值映射元素
boolean remove(Object key,Object value) //删除Map 集合中键值映射同时匹配的元素(JDK8新方法)
void clear() //清空整个Map集合中的键值映射元素
String replace(Object key,Object value) //将Map集合中指定键对象Key所映射的值修改为value (JDK8新方法)

public class Demo13{
    public static void main(String[] args){
        //创建HashMap集合对象
        HashMap<String, String> map = new HashMap<String, String>();
        //T put(Object key, Object value)          //向Map集合中添加指定键值映射的元素
        map.put("hm001","张三");
        map.put("hm002","李四");
        map.put("hm003","王五");
        map.put("hm004","赵六");   //键不能重复,使用新值将老值替换,并返回老值

        //int size()               //返回Map集合键值对映射的个数
        System.out.println(map.size());
        
        //Object get(Object key)    //返回指定键所映射的值,如果此映射不包含该键的映射关系,则返回null
        String value = map.get("hm001");
        System.out.println(value);

        //boolean containsKey(Object key)          //查看Map 集合中是否存在指定的键对象key
        boolean b = map.containsKey("hm002");
        System.out.println(b);

        //boolean containsValue(Object value)      //查看Map 集合中是否存在指定的值对象value 
        b = map.containsValue("李四");
        System.out.println(b);

        //Object remove(Object key)                //删除并返回Map 集合中指定键对象key 的键值映射元素
        map.remove("hm003");
        System.out.println(map);

        //boolean remove(Object key,Object value)  //删除Map 集合中键值映射同时匹配的元素(JDK8新方法)
        map.remove("hm003","赵六");
        System.out.println(map);
        
        //void clear()                             //清空整个Map集合中的键值映射元素
        map.clear();

        //String replace(Object key,Object value)  //将Map集合中指定键对象Key所映射的值修改为value (JDK8新方法)
        map.replace("hm001","葛二蛋");
        System.out.println(map);
        
    }  
}


十三、Map集合遍历

1、过程

(1)调用map集合的KeySet()方法,将所有的key保存到一个Set集合中。
(2)遍历Set集合,拿到每一个key。
(3)调用map集合的get()方法,通过键获取值。

2、集合遍历的方法

2.1 第一种方法 keySet()方法
public class Demo14{
     public static void main(String[] args){
        HashMap<String, String> hm = new HashMap<String, String>();
        hm.put("hm001","张三");
        hm.put("hm002","李四");
        hm.put("hm003","王五");
        
        //第一种方式:keySet()方法
        Set<String> keys = hm.keySet();
        for(String key: keys){
            String value = hm.get(key);
            System.out.println(Key + "=" + value);
        }
}

2.2 第二种方法 entrySet()方法
public class Demo15{
     public static void main(String[] args){
        HashMap<String, String> hm = new HashMap<String, String>();
        hm.put("hm001","张三");
        hm.put("hm002","李四");
        hm.put("hm003","王五");
        
        //第二种方法 entrySet()方法
        Set<Map.Entry<String, String>> entrys = hm.entrySet();
        Iterator<Map.Entry<String, String>> it = entrys.iterator();
        while(it.hasNext())
        {
            Map.Entry<String, String> entry = it.next();
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(Key + "=" + value);
        }

}

2.3 第三种方法 forEach(BiConsumer); JDK8版本新增的遍历方法
public class Demo16{
     public static void main(String[] args){
        HashMap<String, String> hm = new HashMap<String, String>();
        hm.put("hm001","张三");
        hm.put("hm002","李四");
        hm.put("hm003","王五");
        
        //第三种方法 forEach(BiConsumer);  JDK8版本新增的遍历方法
        hm.forEach((String key,String value)->{System.out.println(key + "=" + value);});

        
}

2.4 第四种方法 values(); 获取map集合中所有的值,返回到一个Collection集合中。forEach(); 方法
public class Demo17{
     public static void main(String[] args){
        HashMap<String, String> hm = new HashMap<String, String>();
        hm.put("hm001","张三");
        hm.put("hm002","李四");
        hm.put("hm003","王五");
        
        //第四种方法 values(); 获取map集合中所有的值,返回到一个Collection集合中。forEach(); 方法
        Collection<String> values = hm.values();
        values.forEach((String value)->{System.out.println(value);});
        
}

十四、TreeMap集合

1、介绍

TreeMap集合是Map接口的另一个实现类,在TreeMap内部是通过二叉树的原理来保证键的唯一性,这与TreeSet集合存储的原理是一样,因此TreeMap中所有的键是按照某种顺序排列的。

2、说明

为了实现TreeMap元素排序,可以参考TreeSet集合排序方式,使用自然排序和定制排序

//TreeMap自然排序
public class Demo18{
     public static void main(String[] args){
        TreeMap<String, String> tm = new TreeMap<String, String>();
        tm.put("tm001","张三");
        tm.put("tm002","李四");
        tm.put("tm003","王五");
        
        System.out.println(tm);
        
}

//TreeMap定制排序
//按照年龄的升序排序
public class Demo19{
     public static void main(String[] args){
        TreeMap<String, String> tm = new TreeMap<String, String>(new Comparator<Teacher>(){
            @Override
            public int compare(Teacher t1, Teacher t2)
            {
                return t1.getAge() - t2.getAge();
            }
        });

        tm.put("tm001","张三");
        tm.put("tm002","李四");
        tm.put("tm003","王五");
        
        System.out.println(tm);
        
}

十五、Properties集合

1、介绍

Map接口还有一个实现类Hashtable, 它和HashMap十分相似,其中一个主要区别在于Hashtable是线程安全的。

2、说明

Hashtable类有一个子类Properties。Properties主要用来存储字符串类型的键和值,在实际开发中,经常使用Properties集合类来存取应用的配置项。

3、构造方法

Properties() 创建一个Properties集合对象

4、成员方法

String getProperty(String key) //通过键获取值
void load(InputStream inStream) //从流中读取文件
Object setProperty(String key,String value) //向集合中添加数据
void store(OutputStream out, String comments) //将集合中的数据通过输出流写出到文件中

5、实例一

public class Demo20{
    pubclic class void main(String[] args)
    {
        //创建Properties集合对象
        Properties prop = new Properties();

        //向集合中添加数据
        prop.setProperty("username","admin");
        prop.setProperty("password","123456");

        //获取集合中的数据
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");
        
        System.out.println(username + "===" + password);
    }
}

6、实例二

创建一个config.properties配置文件

#update config
tel = 1888888888
username = admin;
password = 123456;

再创建一个class文件


public class Demo21{
    public static void main(String[] args){
        Properties prop = new Properties();

        prop.load(new FileInputStream(""config.properties));

        String username = prop.getProperty("username");
        String password = prop.getProperty("password");

        System.out.println(username);
        System.out.println(password);

        prop.setProperty("tel","1888888888");
        prop.store(new FileOutputStream("config.properties"),"update config");
    }
}


十六、泛型

集合中可以存储任意类型的对象元素,但是当把一个对象存入集合后,集合会“忘记” 这个对象的类型,将该对象从集合中取出时,这个对象的编译类型就统一变成了Object类型。
也就是说,在程序中无法确定一个集合中的元素到底是什么类型,那么在取出元素时,如果进行强制类型转换就很容易出错。

1、实例

public class Demo22{
    public static void main(String[] args){
        //未进行泛型约束的,存入后默认为object,不好遍历循环
        ArrayList list = new ArrayList();
        list.add(100);
        list.add(true);
        list.add("abc");


        //泛型约束的
        ArrayList<String> list2 = new ArrayList<>();

        list2.add("abc");
        list2.add("bcd");

        for(String s : list2){
            System.out.println(s);
        }
    }
}


十七、Collections工具类

1、说明

Java提供了一个工具类专门用来操作集合,这个类就是Collections, 它位于java.util包中
Collections类中提供了大量的静态方法用于对集合中元素进行排序、查找和修改等操作。

2、相关方法

static boolean addAll(Collection<? super T> c,T… elements) //将所有指定元素添加到指定集合C中
static void reverse(List list) //反转指定List集合中元素的顺序
static void shuffle(List list) //对List集合中的元素进行随机排序
static void sort(List list) //根据元素的自然顺序对List集合中的元素进行排序
static void swap(List list,int i,int j) //指定List集合中角标i处的元素和j处元素进行交换
static int binarySearch(List list,Object key) //使用二分法搜索指定对象在List集合中的索引,查找的List集合中的元素必须是有序的
static Object max(Collection col) //根据元素的自然顺序,返回给定集合中最大的元素
static Object min(Collection col) //根据元素的自然顺序,返回给定集合中最小的元素
static boolean replaceAll(List list,Object oldVal,Object newVal) //用一个新值newVal替换List集合中所有的旧值oldVal

3、相关代码

public class Demo23{
    public static void main(String[] args){
        ArrayList<String> list = new ArrayList<String>();
        
        //static <T> boolean addAll(Collection<? super T> c,T... elements) //将所有指定元素添加到指定集合C中
        Collections.addAll(list,"a","b","c");    //[a,b,c,d]

        //static void reverse(List list)         //反转指定List集合中元素的顺序
        Collections.reverse(list);
        System.out.println(list);                //[d,c,b,a]

        //static void shuffle(List list)         //对List集合中的元素进行随机排序
        Collections.shuffle(list);
        System.out.println(list);              //[a,c,b,d]

        //static void sort(List list)     //根据元素的自然顺序对List集合中的元素进行排序
        Collections.sort(list);
        System.out.println(list);              //[a,b,c,d]

        //static void swap(List list,int i,int j)      //指定List集合中角标i处的元素和j处元素进行交换
        Collections.swap(list,2,3);
        System.out.println(list);         //[a,b,d,c]

        //static int binarySearch(List list,Object key)           //使用二分法搜索指定对象在List集合中的索引,查找的List集合中的元素必须是有序的
        int index = Collections.binarySearch(list, "b");
        System.out.println(index);  

        //static Object max(Collection col)         //根据元素的自然顺序,返回给定集合中最大的元素
        String max = Collections.max(list);
        System.out.println(max);
        
        //static Object min(Collection col)          //根据元素的自然顺序,返回给定集合中最小的元素
        String min = Collections.min(list);
        System.out.println(min);

        //static boolean replaceAll(List list,Object oldVal,Object newVal)  //用一个新值newVal替换List集合中所有的旧值oldVal
        Collections.replaceAll(list, "b","f");
        System.out.println(list);


    }
}

十八、Arrays数组工具类

1、相关方法

void sort(); //对数组排序
String toString(); //打印数组
int binarySearch(Object[] a,Object key); //使用二分查找法获取指定元素在数组中出现的索引位置
int[] copyOfRange(int[] original, int from, int to); //复制数组元素到一个新数组中
void fill(Object[] a,Object val); //使用传入元素替换数组中所有的元素

2、相关代码

public class Demo24{
    public static void main(String[] args){
        int[] arr = {10,30,20,50,40,60}
  
        //void sort();         //对数组排序
        Arrays.sort(arr);
        
        //String toString();   //打印数组
        System.out.println(Arrays.toString(arr));

        //int binarySearch(Object[] a,Object key);   //使用二分查找法获取指定元素在数组中出现的索引位置
        int index = Arrays.binarySearch(arr,50);
        System.out.println(index);

        //int[] copyOfRange(int[] original, int from, int to);   //复制数组元素到一个新数组中
        int[] arr2 = Arrays.copyOfRange(arr,1 ,4);
        System.out.println(Arrays.toString(arr2));

        //void fill(Object[] a,Object val);         //使用传入元素替换数组中所有的元素
        Arrays.fill(arr2,88);
        System.out.println(Arrays.toString(arr2)); //[88, 88, 88]
    }
}

十九、聚合操作

1、介绍

由于原始操作方法(普通循环遍历出每一个元素,然后穿插一些if条件语句选择性的对元素进行查找、过滤、修改等操作)可行,但代码量较大并且执行效率较低,因此JDK8中新增了聚合操作,可以进一步简化集合、数组中元素的查找、过滤、转换等

2、定义

JDK8中新增了一个Stream接口,该接口可以将集合、数组中的元素转换为Stream流的形式,并结合Lambda表达式的优势来进一步简化集合、数组中元素的查找、过滤、转换等操作,这就是聚合操作。

3、操作步骤

(1)将原始集合或者数组对象转换为Stream流对象
(2)对Stream流对象中的元素进行一系列的过滤、查找等中间操作,然后返回一个Stream流对象
(3)对Stream流进行遍历、统计、收集等终结操作,获取想要的结果。

4、实例

/*
*  终结方法:方法的返回值类型是void,就不能再调用其他的方法了
*  非终结方法:方法的返回值类型是Stream流。还可以继续调用其他方法
*/
public class Demo1{
    public static void main(String[] args){
        ArrayList<String> list = new ArrayList<String>();
        list.add("张三");
        list.add("李四");
        list.add("张小明");
        list.add("王五");
        list.add("赵六");

        list.stream().filter((String s)->{return s.startsWith("张");}).limit(2).forEach((String s)->{System.out.println(s);});
    } 
}


二十、创建Stream流对象

1、创建方法

(1)所有的Collection集合都可以使用stream()静态方法获取Stream流对象
(2)Stream接口的of()静态方法可以获取基本类型包装类数组、引用类型数组和单个元素的Stream流对象
(3)Arrays工具类的stream()静态方法也可以获取数组元素的Stream流对象

2、实例

2.1 获取Stream流的方式

(1)通过单列集合的静态方法:stream()获取Stream流对象
(2)通过Stream接口静态方法:of(数组)获取Stream流对象
(3)通过Arrays工具类静态方法:stream(数组)获取Stream流对象

public class Demo25{
    public static void main(String[] args){
        Integer[] arr = {10,20,30,40,50};
        Stream<Integer> s1 = Arrays.stream(arr);
        s1.forEach((Integer i)->{System.out.println(i);});

        Stream<String> s2 = Stream.of("aaa","bbb","ccc");
        s2.forEach((String s)->{System.out.println(s);});

        ArrayList<String> list = new ArrayList<String>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        Stream<String> s3 = list.stream();
        s3.forEach((String s)->{System.out.println(s);});

        HashMap<String, String> map = new HashMap<String, String>();
        map.put("hm001","张三");
        map.put("hm002","李四");
        map.put("hm003","王五");

        Set<String> keys = map.keySet();
        Stream<String> s4 = keys.stream();
    }
}

二十一、Stream流的常用方法

1、Stream流常用操作

Stream filter(Predicate<? super T> predicate) //将指定流对象中的元素进行过滤,并返回一个子流对象
Stream map(Function<? super T,? extends R> mapper) //将流中的元素按规则映射到另一个流中
Stream distinct() //删除流中重复的元素
Stream sorted() //将流中的元素按自然顺序排序
Stream limit(long maxSize) //截取流中元素的长度
Stream skip(long n) //丢弃流中前n个元素
static Stream concat(Stream<? extends T> a.Stream<? extends T> b) //将两个流对象合并为一个流
long count() 统计流中元素的个数
R collect(Collector<? super T, A, R> collector) //将流中的元素收集到一个容器中(如集合)
Object[] toArray() //将流中的元素收集到一个数组中
void forEach(Consumer<? supper T> action) //将流中的元素进行遍历

public class Demo26{
    public static void main(String[] args){
        ArrayList<String> list = new ArrayList<String>();

        list.add("张三");
        list.add("李四");
        list.add("张小明");
        list.add("张果老");
        
        //通过流对象遍历集合元素
        Stream<String> s1 = list.stream();
        s1.forEach((String s)->{System.out.println(s);});

        System.out.println("=====================================");


        //过滤:获取集合中以张为开头并且名字长度大于2
        Stream<String> s2 = list.stream();
        s2.filter((String s)->{return s.startsWith("张")&&s.length()>2;}).forEach(s->System.out.println(s));

        System.out.println("=====================================");


        //筛选+排序:获取集合中以a为开头。将字符串转成大写并排序
        Stream<String> s3 = list.stream();
        s3.filter(s->s.startsWith("a")).map(s->s.toUpperCase()).sorted().forEach(s->System.out.println(s));

        //跳过+截取:跳过前2个字符串,只要3-6个(只要四个字符串)
        Stream<String> s4 = list.stream();
        s4.skip(2).limit(4).forEach(s->System.out.println(s));

        //将流对象的元素转成一个集合:获取集合中以张为开头的字符串。返回一个新的集合中
        Stream<String> s5 = list.stream();
        List<String> list2 = s5.filter(s->s.startsWith("张")).collect(Collectors.toList());
        System.out.println(list2);
    }
}



二十二、Parallel Stream(并行流)

1、种类

1.1 串行流

就是将源数据转换为一个流对象,然后在单线程下执行聚合操作的流。(也就是单一管道流)

1.2 并行流

就是将源数据分为多个子流对象进行多线程操作(也就是多个管道流)然后将处理的结果再汇总为一个流对象。

2、Parallel Stream(并行流)

2.1 原理

Stream并行流底层会将源数据拆解为多个流对象在多个线程中并行执行,这依赖于JDK7中新增的fork/join框架,该框架解决了应用程序并行计算的能力,但是单独使用这个框架,必须指定源数据如何进行详细拆分,而JDK8中的聚合操作,在fork/join框架的基础上进行组合解决了这一麻烦。

2.2 注意

使用Stream并行流在一定程度上可以提升程序的执行效率,但是在多线程执行就会出现线程安全这个大问题,所以为了能够在聚合操作中使用Stream并行流,前提是要执行操作的源数据在并行执行过程中不会被修改。

3、创建

3.1 说明

创建Stream流对象时,除非有特别声明,否则默认创建的都是串行流。

3.2 创建方式

(1)通过Collection集合接口的parallelStream()方法直接将集合类型的源数据转变为Stream并行流
(2)通过BaseStream接口的parallel()方法将Stream串行流转变为Stream并行流。

4、代码

public class Demo27{
    public static void main(String[] args){
        ArrayList<String> list = new ArrayList<String>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");

        //获取到的是串行流
        Stream<String> s1 = list.stream();

        Stream<String> s2 = s1.parallel();

        //获取并行流-通过集合的parallelStream()
        Stream<String> s3 = list.parallelStream();

        System.out.println(s1.isParallel());
        System.out.println(s2.isParallel());
        System.out.println(s3.isParallel());
    } 


}


  • 26
    点赞
  • 173
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 我可以提供一些Java集合相关的面试题,包括:1.什么是集合?2.什么是集合框架?3.HashMap和Hashtable有什么区别?4.ArrayList和LinkedList有什么区别?5.什么是迭代器?6.什么是泛型?7.什么是线程安全的集合?8.什么是同步集合? ### 回答2: Java集合Java中常用的数据结构,提供了许多功能强大且灵活的类和接口,可以方便地处理各种数据操作。下面我将回答一些常见的和Java集合相关的面试题。 1. 请解释一下Java集合框架。 Java集合框架是一组用来存储和操作数据的类和接口的集合。它提供了各种集合类型(如List、Set、Map等),以及用于集合操作的方法和算法。Java集合框架的设计目标是提供高性能、可靠性和安全性的数据结构,同时将最小的编程复杂性和性能开销传递给开发人员。 2. List和Set之间有什么区别? List是一个有序的集合,允许重复元素。可以通过索引访问集合中的元素。Set是一个不包含重复元素的集合,不保证元素的顺序。在List中,元素可以根据插入的顺序进行访问和遍历,而在Set中,无法根据插入的顺序访问元素。 3. HashMap和HashTable有什么区别? HashMap和Hashtable都是实现了Map接口的键值对集合。主要区别在于HashMap是非线程安全的,而Hashtable是线程安全的。此外,HashMap允许使用null键和null值,而Hashtable不允许。在性能上,HashMap要优于Hashtable,因为HashMap使用了更高效的哈希算法。 4. 请解释一下ArrayList和LinkedList之间的差异。 ArrayList和LinkedList都是List接口的实现类。ArrayList是基于动态数组实现的,因此在随机访问和获取元素时性能较好。而LinkedList是基于双向链表实现的,因此在插入和删除元素时性能较好。因此,如果需要频繁进行随机访问操作,则应选择ArrayList;如果需要频繁进行插入和删除操作,应选择LinkedList。 5. 请解释一下迭代器(Iterator)是什么? 迭代器是用于遍历集合中元素的对象。由于不同的集合类型内部的数据结构不同,使用通用的for循环进行遍历时可能会有问题。迭代器提供了一种统一的方式来遍历集合,无论集合内部的数据结构如何,都能够正确地获取元素。可以使用迭代器的方法来逐个访问和操作集合中的元素。 ### 回答3: 面试题一: ArrayList和LinkedList有什么区别? ArrayList和LinkedList都是Java集合框架中的List接口的实现类,它们的主要区别在于底层数据结构和性能。 ArrayList底层使用数组实现,它的读取效率很高,时间复杂度为O(1),但是在插入和删除元素时会导致数组的扩容和复制,时间复杂度为O(n)。因此,适合对元素的访问操作较多,而对插入和删除操作较少的场景。此外,ArrayList还支持随机访问,可以通过索引来直接访问元素。 LinkedList底层使用双向链表实现,它的插入和删除操作效率很高,时间复杂度为O(1),因为只需要改变前后节点的指针即可。但是在读取元素时需要从头开始遍历链表,时间复杂度为O(n)。因此,适合对插入和删除操作较多,而对元素的访问操作较少的场景。此外,LinkedList还支持快速的头部和尾部操作。 总结起来,ArrayList适用于元素访问频繁的场景,而LinkedList适用于插入和删除频繁的场景。 面试题二: HashSet和TreeSet有什么区别? HashSet和TreeSet都是Java集合框架中的Set接口的实现类,它们的主要区别在于元素的存储和排序方式。 HashSet底层使用哈希表实现,它不保证元素的顺序,存储和检索的速度都很快,时间复杂度为O(1)。HashSet使用元素的hashCode()方法和equals()方法来判断元素的唯一性,因此要求元素必须实现hashCode()和equals()方法。 TreeSet底层使用红黑树实现,它可以对元素进行排序,默认按照元素的自然顺序进行排序,或者通过传入的Comparator对象来进行自定义排序。TreeSet的存储和检索速度较慢,时间复杂度为O(logn)。TreeSet要求元素必须实现Comparable接口或者在构造TreeSet时传入Comparator对象来进行比较。 总结起来,HashSet适用于需要快速存储和检索元素,并且不需要考虑元素的排序的场景。而TreeSet适用于需要对元素进行排序的场景。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊凯瑞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值