1.set
1.1、set和list有一个不同点就是set不可以存放重复的元素而list可以。set如何保证这一特点。
根据源码可以看出hashset中的add方法最后会调用hashmap中的put方法。
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
首先会根据hashcode这个方法返回hash值,先判断hash值之后在通过equals方法判断内容。
1.2hashset与treeset区别
1.2.1、h底层是个hash表可以存放null,treeset底层是个二叉树不可以存null。
1.2.2、h上面说过怎么保证唯一性。treeset通过compareTo方法。
一般排序的时候使用t,因为当需要一个有序的数据的时候散列表中存储的时无序的数据,还需要排序。treeset可以重写comperto方法对数据进行自定义升序排序。
2.list
2.1、list循环问题
2.1.1
list在使用for循环的时候,会生成一个iterator对集合进行迭代,此时又对这个集合修改会出现ConcurrentModificationException 异常。
2.1.2
//建立一个list集合,里面有5个元素含有“a”,3个不含有“a”
List<String> list = new ArrayList<>();
list.add("abc");
list.add("anc");
list.add("amg");
list.add("agf");
list.add("omg");
list.add("aig");
list.add("gme");
list.add("wbe");
//遍历集合,移除含有“a”的元素
for(int i = 0; i < list.size();i++){
String str = list.get(i);
if(str.contains("a")){
list.remove(i);
}
}
//打印,看结果
for (Object st : list) {
System.out.print(st+" ");
}
运行结果:
这里是想要把所有带a的字符串删除。但是每当删除的时候集合的结构都会向前移动一位,破坏了集合的结构导致逻辑错误。
通过迭代器中的remove方法进行删除得到正确的结果。
Iterator<String> iterator=list.iterator();
while (iterator.hasNext()){
if (iterator.next().contains("a")){
iterator.remove();
}
}
2.2、数组与集合的相互转换
2.3、多线程场景下如何使用arraylist
3.list转换成map的三种方式:
3.1、第一种通过遍历向map中添加数据
List<Srudent> srudentList = new ArrayList<Srudent>();
srudentList.add(new Srudent(1, "张朝阳"));
srudentList.add(new Srudent(6, "朱朝阳"));
srudentList.add(new Srudent(3, "李朝阳"));
srudentList.add(new Srudent(4, "吴朝阳"));
HashMap<Integer, Srudent> integerSrudentHashMap = new HashMap<Integer, Srudent>();
Iterator<Srudent> iterator=srudentList.iterator();
int num=0;
while (iterator.hasNext()){
integerSrudentHashMap.put(++num,iterator.next());
}
for (Integer key : integerSrudentHashMap.keySet()){
System.out.println(key +"-----"+integerSrudentHashMap.get(key).toString());
}
3.2、第二种通过流的方式
Map<Integer, Srudent> integerSrudentHashMap =srudentList.stream().collect(Collectors.toMap(p->p.getAge(),(p) ->p ));
for (Integer key : integerSrudentHashMap.keySet()){
System.out.println(key+"======="+integerSrudentHashMap.get(key));
}
3.流在集合中的使用
3.1流对于list
//打印
List<Srudent> srudentList = new ArrayList<Srudent>();
srudentList.add(new Srudent(1, "张朝阳"));
srudentList.add(new Srudent(2, "朱朝阳"));
srudentList.add(new Srudent(3, "李朝阳"));
srudentList.add(new Srudent(4, "吴朝阳"));
srudentList.stream().forEach(System.out::println);
//获取集合长度
System.out.println(srudentList.stream().count());
//去重
srudentList.distinct().forEach(System.out::println);
// 将stream流处理后的数据收集成一个集合
//去重返回一个集合
List<Srudent> collect = srudentList.stream().distinct().collect(Collectors.toList());
//过滤 , filter是满足条件的留下,是对原数组的过滤;map则是对原数组的加工,映射成一对一映射的新数组。说人话就是改变了了长度了用filter,没改变长度,只是对某一个或者几个做改变用map。
arrayList.stream().filter(p -> p.contains("李")).forEach(System.out::println);
//分组,这里想要将同岁的学生分为一组
List<Srudent> srudentList = new ArrayList<Srudent>();
srudentList.add(new Srudent(24,"孙千"));
srudentList.add(new Srudent(24,"小时代"));
srudentList.add(new Srudent(33,"郭敬明"));
srudentList.add(new Srudent(34,"张大大"));
Map<Integer, List<String>> collect = srudentList.stream().collect(Collectors.groupingBy(Srudent::getAge, Collectors.mapping(Srudent::getName, Collectors.toList())));
System.out.println(collect);