Java基础-集合2

Map

  • 存放的一对值 (key-value);其中的key值不能重复

1.1.HashMap

  • HashMap结合了数组和链表的优势
  • 底层是哈希表(hash表/映射表),jdk8的底层是 数组和单向链表+红黑树
  • 什么是哈希表,是一种数据结构,用到了hash算法
  • hash算法,将无限的数据映射到有限的数据范围内;抽屉原理 9个,20 ,2个苹果会放到一个抽屉中;如果能做到结果尽可能分散,算法较优秀,如果得到的hash值一样会发生hash冲突
  • HashMap没有做任何的线程同步,在多线程情况下不安全;
 public static void main(String[] args) {
     
        Map<String, String> stringMap = new HashMap<>();
        stringMap.put("1", "a");
        stringMap.put("2", "b");
        stringMap.put("1", "java");
        System.out.println(stringMap);
        //根据 key 取出来对应的value 值
        System.out.println(stringMap.get("1"));
        System.out.println("获取键值对个数:" + stringMap.size());
        System.out.println("是否包含某个key值:" + stringMap.containsKey("2"));
        System.out.println("是否包含某个value值:" + stringMap.containsValue("abc"));
        // 根据key进行删除
//       stringMap.remove("1");
//       stringMap.clear();
        System.out.println(stringMap);
        //map的遍历
        stringMap.forEach((key, value) -> {
     
            System.out.println(key);
            System.out.println(value);
        });
    }

源码解析:

1,put方法

​ 两个key对象不同,hashcode值不同hash值也不同,但是取模之后得到的索引值是一样的,会冲突

​ 两个key对象不同,但是hashcode值相同,取模之后得到的索引值是一样的,会冲突

2,get方法

3,resize()方法,首次扩容,默认值是16;否则的话会进行元素移动(旧的数组索引位对应的元素会移动到高位或者地位)

4,key的数据类型需要选择不可变的数据类型,比如String,Integer这些

//map中的key是不能重复的,String是不可变的非常合适作为key
        HashMap<String, Integer> map = new HashMap<>();
        String str = "a";
        map.put(str, 123);
        str += "ab";
        map.put(str, 234);
        System.out.println(map);
//StringBuilder是可变的,不能作为key
        HashMap<StringBuilder, Integer> map1 = new HashMap<>();
        StringBuilder stringBuilder = new StringBuilder("a");
        map1.put(stringBuilder,123);
        stringBuilder.append("ab");
        map1.put(stringBuilder,234);
        System.out.println(map1);

1.2.LinkedHashMap

  • 底层使用双向链表结构保持集合元素的插入顺序,使访问顺序与插入顺序一致
		LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("123","abc");
        linkedHashMap.get("1");

1.3.TreeMap

  • 对插入的key值进行自然排序,底层是红黑树;
  • TreeMap的key 要么实现Comparable接口,要么是new TreeMap实例的时候传入一个Comparator实现类(匿名内部类或者lambda表达式)
public static void main(String[] args) {
     
        TreeMap<Integer, String> trM = new TreeMap<>();
        trM.put(45,"abc");
        trM.put(12,"aaa");
        trM.put(1,"ccc");
        System.out.println(trM.get(12));
        //获取最小的key值
        System.out.println(trM.firstKey());
        //获取的最大key值
        System.out.println(trM.lastKey());
        System.out.println(trM.firstEntry());
    }

1.4.HashTable

  • 是线程安全的map,内部做了方法同步,效率比较低;锁的是整个hash表
  • ConcurrentHashMap是高并发情况下使用的一个map,上锁是分段锁(jdk7),性能比HashTable优秀
		Hashtable<String, String> ha = new Hashtable<>();
        ha.put("1", "abc");
        ha.get("1");
        ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap();
        concurrentHashMap.put("1", "abc");

1.5. map的遍历

public static void main(String[] args) {
     
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "aa");
        hashMap.put(12, "aa");
        hashMap.put(23, "aa");
        hashMap.put(43, "aa");
        //1,for循环遍历
        Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
        for (Map.Entry<Integer, String> entry : entries) {
     
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }
        System.out.println("=======================");
        //2,使用forEach进行遍历
        hashMap.forEach((k, v) -> {
     
            System.out.println(k + " : " + v);
        });
        System.out.println("+++++++++++++++++++++++++");
        //3,先获取key的集合
        Set<Integer> integers = hashMap.keySet();
        for (Integer integer : integers) {
     
            System.out.println(integer + " : " + hashMap.get(integer));
        }
        // 获取map中value的集合
        Collection<String> values = hashMap.values();
        System.out.println(values);
    }

1.6.集合遍历注意点

  • 遍历过程中不要直接去使用集合删除元素或者改动集合modCount的操作,如果要改动,使用迭代器
public static void main(String[] args) {
     
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "a");
        hashMap.put(2, "a");
        hashMap.put(3, "a");
        Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
        Iterator<Map.Entry<Integer, String>> iterator1 = entries.iterator();
        while (iterator1.hasNext()){
     
            Map.Entry<Integer, String> next = iterator1.next();
            if (next.getKey()==1){
     
                iterator1.remove();
            }
        }
   /*     hashMap.forEach((k, v) -> {
            if (k == 1) {
                hashMap.remove(k);
            }
        });*/
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(1);
        arrayList.add(3);

        Iterator<Integer> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
     
            Integer next = iterator.next();
            if (next == 1) {
     
                iterator.remove();
            }
        }
        /*arrayList.forEach(new Consumer() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
                if (integer == 1) {
                    arrayList.remove(integer);
                }
            }
        });*/

        System.out.println(arrayList);
        /*ArrayList strings3 = new ArrayList<>();
        strings3.add("a");
        // set中元素是不可重复的, map的key也是不可重复的
        HashSet strings = new HashSet<>();
        HashMap map = new HashMap<>();
        strings.add("a");
        strings.add("a"); //
        System.out.println(strings);
        LinkedHashSet strings1 = new LinkedHashSet<>();
        strings1.add("a");
        TreeSet strings2 = new TreeSet<>();
        strings2.add("a");
        TreeMap objectObjectTreeMap = new TreeMap<>();*/
    }

1.7. Collections常用方法

public static void main(String[] args) {
     
        ArrayList<String> strings = new ArrayList<>();
        strings.add("a"); //
        // Collections.addAll  将所有指定的元素添加到指定的集合。 可变长参数是可以传0或者多个
        Collections.addAll(strings, "1", "hello", "Abc", "a");
        System.out.println("排序前:" + strings);
        //根据其元素的自然顺序对指定的列表进行排序。
        Collections.sort(strings);
        System.out.println("排序后:" + strings);
        System.out.println("最大值:" + Collections.max(strings));
        System.out.println("最小值:" + Collections.min(strings));
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("a");
        //返回指定源列表中指定目标列表的第一次出现的起始位置,如果没有此列表,则返回-1。
        int i = Collections.indexOfSubList(strings, arrayList);
        System.out.println("子list的起始索引:" + i);
        System.out.println("子list的最后一次出现的起始索引" + Collections.lastIndexOfSubList(strings, arrayList));
        List<Object> objects = Collections.emptyList();
        // 用指定的元素代替指定列表中的所有元素。
        Collections.fill(strings,"world");
        System.out.println(strings);
        // 集合中的泛型要实现Comparable接口
        ArrayList<Bike> bikes = new ArrayList<>();
        Collections.sort(bikes);
    }

1.8. Stream流操作

强大了对集合的操作,提供较多的功能

1,中间操作:方法调用后返回值类型是Stream,其实就是返回的流

​ map():对流中的元素进行相同的操作后得到新的流元素

​ sorted():对流中的元素进行排序

​ filter():根据指定的规则对流中的元素进行过滤

​ limit (long maxSize):按指定长度截断流

2,终止操作:只能出现一个而且必需在最后出现

​ count() :得到流中的元素个数

​ collect() :收集流元素,可以转换为一个list

​ max():得到最大值
​ min():得到最小值

​ reduce()流元素进行合并

 		ArrayList<Integer> arrayList = new ArrayList<>();
        String[] strings = new String[10];
        //1,生成流的方式,
        //把数组转成流
        Stream<String> stream1 = Arrays.stream(strings);
        Stream<Integer> strings1 = Stream.of(1, 2, 3, 4, 5);
        //把list转成流
        Stream<Integer> stream = arrayList.stream();
public static void main(String[] args) {
     
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(10);
        arrayList.add(9);
        arrayList.add(18);
        arrayList.add(32);
        arrayList.add(6);
        System.out.println(arrayList);
        Stream<Integer> stream = arrayList.stream();
        //
        Optional<Integer> max = stream.map(a -> {
     
            return a * 1;
        }).filter(e -> {
     
            if (e > 1) {
     
                // 返回值为true 表示留下的;否则就是过滤掉的
                return true;
            }
            return false;
        }).limit(5).reduce((a, b) -> {
     
            return a * b;
        });
        //collect(Collectors.toList());
        System.out.println(max.get());
    }

可变长参数

public static void main(String[] args) {
     
        String[] strs = {
     "a", "b", "c"};
        method1(strs);
        method1("a", "b", "c");
//        Stream strs1 = Stream.of(strs);
    }
    /**
     * 本质上是个数组
     * @param strings
     */
    public static void method1(String... strings) {
     
        int length = strings.length;
        for (int i = 0; i < strings.length; i++) {
     
            System.out.println(strings[i]);
        }
    }

你可能感兴趣的:(Java基础,java)