list的遍历
package com.miracle.luna.lambda; import java.util.ArrayList; import java.util.List; /** * @Author Miracle Luna * @Date 2019/6/9 23:36 * @Version 1.0 */ public class ListLambda { public static void main(String[] args) { List<String> items = new ArrayList<>(); items.add("A"); items.add("B"); items.add("C"); // 普通for循环遍历 System.out.println("第一种遍历方式:普通for循环遍历 List 集合"); for (int i = 0; i < items.size(); i++) { System.out.println(items.get(i)); } // 增强for循环遍历 System.out.println(" 第二种遍历方式:增强for循环遍历 List 集合"); for (String item : items) { System.out.println(item); } // Lambda 表达式遍历(JDK 1.8) System.out.println(" 第三种遍历方式:Lambda 表达式遍历 List 集合"); items.forEach(item->{ System.out.println(item); }); // Lambda 表达式遍历(JDK 1.8) System.out.println(" 第四种遍历方式:Lambda 表达式遍历 List 集合"); items.forEach(System.out::println); // 普通for循环遍历,判断判断是否包含字符串“C” System.out.println(" 第一种判断方式:普通for循环遍历,判断是否包含字符串“C”"); for (int i = 0; i < items.size(); i++) { if ("C".equals(items.get(i))){ System.out.println(items.get(i)); } } // 增强for循环遍历,判断判断是否包含字符串“C” System.out.println(" 第二种判断方式:增强for循环遍历,判断是否包含字符串“C”"); for (String item : items) { if ("C".equals(item)){ System.out.println(item); } } // Lambda 表达式 判断是否包含字符串“C”(JDK 1.8) System.out.println(" 第三种判断方式:Lambda 表达式,判断是否包含字符串“C”"); items.forEach(item->{ if ("C".equals(item)){ System.out.println(item); } }); // Lambda 表达式 判断是否包含字符串“C”(JDK 1.8) System.out.println(" 第四种判断方式:Lambda 表达式,判断是否包含字符串“C”"); items.stream().filter(s->s.contains("C")).forEach(System.out::println);
} }
使用迭代器的方式
import java.util.ArrayList; public class Demo03 { public static void main(String[] args) { ArrayList<News> list = new ArrayList<News>(); list.add(new News(1,"list1","a")); list.add(new News(2,"list2","b")); list.add(new News(3,"list3","c")); list.add(new News(4,"list4","d")); Iterator<News> iter = list.iterator(); while (iter.hasNext()) { News s = (News) iter.next(); System.out.println(s.getId()+" "+s.getTitle()+" "+s.getAuthor()); } } }
list泛型的具体操作
(1).list中添加,获取,删除元素;
添加方法是:.add(e);
获取方法是:.get(index);
删除方法是:
remove(index); 按照索引删除;
remove(Object o); 按照元素内容删除;
List<String> person=new ArrayList<>(); person.add("jackie"); person.add("peter"); person.add("annie"); person.add("martin"); person.add("marry"); person.remove(3); //.remove(index) person.remove("marry"); //.remove(Object o) String per=""; per=person.get(1); System.out.println(per); for (int i = 0; i < person.size(); i++) { System.out.println(person.get(i)); }
list中根据索引将元素数值改变(替换);
.set(index, element); 和 .add(index, element); 的不同;
String a="白龙马", b="沙和尚", c="八戒", d="唐僧", e="悟空"; List<String> people=new ArrayList<>(); people.add(a); people.add(b); people.add(c); people.set(0,d); //.set(index,element); people.add(1,e); //.add(index,element) //增强for循环遍历list for(String str:people){ System.out.println(str); }
.判断list是否为空;
//空则返回true,非空则返回false if (person.isEmpty()) { System.out.println("空的"); }else { System.out.println("不是空的"); }
其他
package test object listDemo { def main(args: Array[String]): Unit = { val list: List[String] = List("a", "b" ,"a") //为列表预添加元素 println("A" +: list) //在列表开头添加元素 println("c" :: list) //在列表开头添加指定列表的元素 println(List("d","e") ::: list) //复制添加元素后列表 println(list :+ "1") //将列表的所有元素添加到 StringBuilder val sb = new StringBuilder("f") println(list.addString(sb)) //指定分隔符 println(list.addString(sb,",")) //通过列表索引获取元素 println(list.apply(0)) //检测列表中是否包含指定的元素 println(list.contains("a")) //将列表的元素复制到数组中,在给定的数组xs中填充该列表的最多为长度(len)元素,从start位置开始。 val a = Array('a', 'b', 'c') val b : Array[Char] = new Array(5) a.copyToArray(b,0,1) b.foreach(println) //去除列表的重复元素,并返回新列表 println(list.distinct) //丢弃前n个元素,并返回新列表 println(list.drop(1)) //丢弃最后n个元素,并返回新列表 println(list.dropRight(1)) //从左向右丢弃元素,直到条件p不成立 println(list.dropWhile(_.equals("a"))) //检测列表是否以指定序列结尾 println(list.endsWith(Seq("a"))) //判断是否相等 println(list.head.equals("a")) //判断列表中指定条件的元素是否存在,判断l是否存在某个元素 println(list.exists(x=> x == "a")) //输出符号指定条件的所有元素 println(list.filter(x=> x.equals("a"))) //检测所有元素 println(list.forall(x=> x.startsWith("b"))) //将函数应用到列表的所有元素 list.foreach(println) //获取列表的第一个元素 println(list.head) //从指定位置 from 开始查找元素第一次出现的位置 println(list.indexOf("b",0)) //返回所有元素,除了最后一个 println(list.init) //计算多个集合的交集 println(list.intersect(Seq("a","b"))) //检测列表是否为空 println(list.isEmpty) //创建一个新的迭代器来迭代元素 val it = list.iterator while (it.hasNext){ println(it.next()) } //返回最后一个元素 println(list.last) //在指定的位置 end 开始查找元素最后出现的位置 println(list.lastIndexOf("b",1)) //返回列表长度 println(list.length) //通过给定的方法将所有元素重新计算 list.map(x=> x+"jason").foreach(println) //查找最大元素 println(list.max) //查找最小元素 println(list.min) //列表所有元素作为字符串显示 println(list.mkString) //使用分隔符将列表所有元素作为字符串显示 println(list.mkString(",")) //列表反转 println(list.reverse) //列表排序 println(list.sorted) //检测列表在指定位置是否包含指定序列 println(list.startsWith(Seq("a"),1)) //计算集合元素之和,这个地方必须是int类型,如果是string直接报错 //println(list.sum) //返回所有元素,除了第一个 println(list.tail) //提取列表的前n个元素 println(list.take(2)) //提取列表的后n个元素 println(list.takeRight(1)) //列表转换为数组 println(list.toArray) //返回缓冲区,包含了列表的所有元素 println(list.toBuffer) //List 转换为 Map val arr = Array(("jason", 24), ("jim", 25)) arr.toMap.foreach(println) //List 转换为 Seq println(list.toSeq) //List 转换为 Set println(list.toSet) //列表转换为字符串 println(list.toString()) } }
set集合的三种遍历方式
1.利用迭代器进行 ,迭代遍历:
Set<Object> sets = new HashSet<Object>();
Iterator<Object> it = set.iterator();
while (it.hasNext()) {
String str = (String)it.next();
System.out.println(str);
}
2.for循环遍历:
for (String str : sets) {
System.out.println(str);
}
3.Set<Object> set = new HashSet<Object>();
foreach循环遍历:
for (Object obj: sets) {
if(obj instanceof Integer){
int aa= (Integer)obj;
}else if(obj instanceof String){
String aa = (String)obj
}
……..
}
ArrayList实现原理要点概括
参考文献:
http://zhangshixi.iteye.com/blog/674856l
https://www.cnblogs.com/leesf456/p/5308358.html
ArrayList是List接口的可变数组非同步实现,并允许包括null在内的所有元素。
底层使用数组实现
该集合是可变长度数组,数组扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量增长大约是其容量的1.5倍,这种操作的代价很高。
采用了Fail-Fast机制,面对并发的修改时,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险
remove方法会让下标到数组末尾的元素向前移动一个单位,并把最后一位的值置空,方便GC
LinkedList实现原理要点概括
参考文献:
1.http://www.cnblogs.com/ITtangtang/p/3948610.htmll
2.https://www.cnblogs.com/leesf456/p/5308843.html
LinkedList是List接口的双向链表非同步实现,并允许包括null在内的所有元素。
底层的数据结构是基于双向链表的,该数据结构我们称为节点
双向链表节点对应的类Node的实例,Node中包含成员变量:prev,next,item。其中,prev是该节点的上一个节点,next是该节点的下一个节点,item是该节点所包含的值。
它的查找是分两半查找,先判断index是在链表的哪一半,然后再去对应区域查找,这样最多只要遍历链表的一半节点即可找到
HashMap实现原理要点概括
参考文献:http://zhangshixi.iteye.com/blog/672697
参考文献:http://blog.csdn.net/lizhongkaide/article/details/50595719
HashMap是基于哈希表的Map接口的非同步实现,允许使用null值和null键,但不保证映射的顺序。
底层使用数组实现,数组中每一项是个单向链表,即数组和链表的结合体;当链表长度大于一定阈值时,链表转换为红黑树,这样减少链表查询时间。
HashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Node对象。HashMap底层采用一个Node[]数组来保存所有的key-value对,当需要存储一个Node对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Node时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Node。
HashMap进行数组扩容需要重新计算扩容后每个元素在数组中的位置,很耗性能
采用了Fail-Fast机制,通过一个modCount值记录修改次数,对HashMap内容的修改都将增加这个值。迭代器初始化过程中会将这个值赋给迭代器的expectedModCount,在迭代过程中,判断modCount跟expectedModCount是否相等,如果不相等就表示已经有其他线程修改了Map,马上抛出异常
Hashtable实现原理要点概括
参考文献:http://blog.csdn.net/zheng0518/article/details/42199477
Hashtable是基于哈希表的Map接口的同步实现,不允许使用null值和null键
底层使用数组实现,数组中每一项是个单链表,即数组和链表的结合体
Hashtable在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。Hashtable底层采用一个Entry[]数组来保存所有的key-value对,当需要存储一个Entry对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。
synchronized是针对整张Hash表的,即每次锁住整张表让线程独占
ConcurrentHashMap实现原理要点概括
参考文献:http://blog.csdn.net/zheng0518/article/details/42199477
ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。
它使用了多个锁来控制对hash表的不同段进行的修改,每个段其实就是一个小的hashtable,它们有自己的锁。只要多个并发发生在不同的段上,它们就可以并发进行。
ConcurrentHashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。Hashtable底层采用一个Entry[]数组来保存所有的key-value对,当需要存储一个Entry对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。
与HashMap不同的是,ConcurrentHashMap使用多个子Hash表,也就是段(Segment)
ConcurrentHashMap完全允许多个读操作并发进行,读操作并不需要加锁。如果使用传统的技术,如HashMap中的实现,如果允许可以在hash链的中间添加或删除元素,读操作不加锁将得到不一致的数据。ConcurrentHashMap实现技术是保证HashEntry几乎是不可变的。
HashSet实现原理要点概括
HashSet是Set接口的典型实现,HashSet按照Hash算法来存储集合中的元素。存在以下特点:
- 不能保证元素的顺序,元素是无序的
- HashSet不是同步的,需要外部保持线程之间的同步问题
- 集合元素值允许为null
list,map,set的区别
list,map,set的区别 (首先假定小猪都是同一个细胞克隆出来的)
List = 排成一长队的小猪
Map = 放在一个个,有房间号的屋子里面的一群小猪
Set = 一群小猪贴上号,然后赶到一个猪圈里
Hashset 它不保证集合的迭代顺序;特别是它不保证该顺序恒久不变。
LinkedHashSet定义了迭代顺序,即按照将元素插入到集合中的顺序(插入顺序)进行迭代。
参考文献:http://zhangshixi.iteye.com/blog/673789l
LinkedHashMap继承于HashMap,底层使用哈希表和双向链表来保存所有元素,并且它是非同步,允许使用null值和null键。
基本操作与父类HashMap相似,通过重写HashMap相关方法,重新定义了数组中保存的元素Entry,来实现自己的链接列表特性。该Entry除了保存当前对象的引用外,还保存了其上一个元素before和下一个元素after的引用,从而构成了双向链接列表。
LinkedHashSet实现原理要点概括
参考文献:http://zhangshixi.iteye.com/blog/673319l
对于LinkedHashSet而言,它继承与HashSet、又基于LinkedHashMap来实现的。LinkedHashSet底层使用LinkedHashMap来保存所有元素,它继承与HashSet,其所有的方法操作上又与HashSet相同。