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<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
if (integer == 1) {
arrayList.remove(integer);
}
}
});*/
System.out.println(arrayList);
/*ArrayList<String> strings3 = new ArrayList<>();
strings3.add("a");
// set中元素是不可重复的, map的key也是不可重复的
HashSet<String> strings = new HashSet<>();
HashMap<String, Object> map = new HashMap<>();
strings.add("a");
strings.add("a"); //
System.out.println(strings);
LinkedHashSet<String> strings1 = new LinkedHashSet<>();
strings1.add("a");
TreeSet<String> strings2 = new TreeSet<>();
strings2.add("a");
TreeMap<Object, Object> 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<String> 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]);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192956.html