-
2021-10-27 11:13:02
为什么要用Lambda表达式和Stream流做集合的处理? 因为效率高、代码简洁、高端大气上档次啊!
现在有以下一个场景:需要将集合 A:{"id": "12345","name": "zhangsan"} B:{"id": "12345", "age": 23} 合并成一个新的集合 C:{"id": "12345","name": "zhangsan", "age": 23}
1、将listA集合转换为map Map<String, Person> map = listA.stream().collect (Collectors.toMap(Person ::getId, Person -> Person)) 2、合并数据,这里将listA集合的数据合并到listB集合上 listB.forEach(n -> { if(map.containsKey(n.getId())){ Person person = map.get(n.getId()); n.setName(person.getName()); } }); 3、如果主键重复了,还可以使用以下方式去重 Map<String, Person> person = listB.stream() .collect(Collectors.toMap(Person::getId, Function.identity(), (key1, key2) -> key2));
其余干货!
1、一个集合根据主键msisdn去重,得到一个新的集合 List<Card> newList = list.stream().collect(Collectors.collectingAndThen( Collectors.toCollection(() ->new TreeSet<>(Comparator.comparing(Card::getMsisdn))), ArrayList::new));
2、获取一个集合中,某个对象指定属性的集合 List<Long> msisdnList = kqCardList.stream().map(KqCard::getMsisdn).collect(Collectors.toList());
3、将一个long类型的集合转换为String类型的集合 List<String> msisdnStrList = msisdnList.stream().map(String::valueOf).collect(Collectors.toList());
4、遍历一个集合中,对每个对象的指定属性进行赋值(这里我对每个对象赋值了三个参数,最后一个是使用UUID做主键) List<CmiDataAmount> cmiDataAmountList = cmiDataAmountList.stream().map( cmiDataAmount ->{cmiDataAmount.setCreateTime(createTime); cmiDataAmount.setCurrentMonth(currentMonth); cmiDataAmount.setId(UUID.randomUUID().toString()); }).collect(Collectors.toList());
5、将String类型的字符串(比如用“,”分割)转换为集合 List<String> msisdnsList = Arrays.asList(msisdns.split(",")).stream(). map(s -> String.format(s.trim())).collect(Collectors.toList());
6、遍历集合,获取类型为A的元素,并放入新集合 List<CmiDataAmount> list = cmiDataAmountList.stream(). filter(item -> item.getType().equals("A")). collect(Collectors.toList());
7、取list集合中的两个元素,转换为一个map Map<Integer, String> collect = list.stream(). collect(Collectors.toMap(Student::getAge, Student::getName));
8.List<Map>转成一个Map // 不想覆盖,保留最初的值: lists.stream().flatMap(m -> m.entrySet().stream()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a)); // 覆盖key相同的值, lists.stream().flatMap(m -> m.entrySet().stream()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> b));
9、如何将一个元素(对象、属性等)优雅的转换为一个集合 List<K> authcChannels = Stream.of(K).collect(Collectors.toList());
更多相关内容 -
List集合
2021-01-09 10:58:14一.List集合概述和特点 在java.util包下,使用要导包 < E >表示List集合中元素的类型
一.List集合概述和特点
在java.util包下,使用要导包< E >表示List集合中元素的类型
继承自Collection接口,所以Collection接口中有的功能List都可以使用。List集合是有索引的。
与Set集合不同,List列表允许重复元素。
代码演示:
List集合的遍历代码演示:package collect; import java.util.Collection; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class CollectionDemo { public static void main(String[] args) { List<String> list=new ArrayList<String>(); list.add("hello"); list.add("java"); Iterator<String> it=list.iterator(); while(it .hasNext()) { String s=it.next(); System.out.println(s); } } }
二.List集合的特有方法
List集合的特有方法Collection集合是没有的,但是他的儿子ArrayList集合有1.void add方法
package collect; import java.util.Collection; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class CollectionDemo { public static void main(String[] args) { List<String> list=new ArrayList<String>(); list.add("hello"); list.add("java"); list.add(1,"xxx"); Iterator<String> it=list.iterator(); while(it .hasNext()) { String s=it.next(); System.out.println(s); } } }
输出:
hello xxx java
可在索引处插入元素
2. E remove方法(E是返回类型):
package collect; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class CollectionDemo { public static void main(String[] args) { List<String> list=new ArrayList<String>(); list.add("hello"); list.add("java"); list.add(1,"xxx"); list.remove(0); Iterator<String> it=list.iterator(); while(it .hasNext()) { String s=it.next(); System.out.println(s); } } }
输出:
xxx java
遍历List集合(使用size方法和get方法):
-
java jdk8 使用stream实现两个list集合合并成一个list集合(对象属性的合并)
2022-01-14 16:38:11目录一、前言二、示例示例1:java8 合并两个 list示例2:java8 合并两个 list示例3:java8 合并两个 list,集合个数前者小于后者,要后者示例4:java8 合并两个 list,集合个数前者大于后者,要后者 一、前言 为什么...java使用stream实现list中对象属性的合并:
根据两个List中的某个相同字段合并成一条List,包含两个List中的字段
目录
一、前言
为什么要用
Lambda表达式
和Stream流
做集合的处理? 因为效率高、代码简洁、高端大气上档次!(1)描述:比如一个List集合中List<对象1>,该对象1包含A、B和C列;另外一个List集合中List<对象2>,该对象2包含A、D列;
(2)问题:需要将两个List合成List<对象3>返回,该对象3包含A、B、C、D列
(3)实现:使用stream实现两个list集合合并成一个list集合
简要说明:filter的使用方式为: filter(item -> item的逻辑判断 ) ,其中filter会保留判断条件为true的记录
二、示例
示例1:java8 合并两个 list<map>
java8 合并两个 list<map>, 并将userId 相同的所有属性合并到一个map中
list1中对象的属性:userId、userName
list2中对象的属性:userId、gender、age
最总集合中对象的属性:userId、userName、gender、ageimport java.util.*; import java.util.stream.Collectors; /** * @author qzz */ public class ListTest { public static void main(String[] args) { mergeList(); } /** * @Description: 合并两个list<map>,并将userId相同的其它属性合并 * @Title: mergeList * @param: @return * @return: List<Map<String,Object>> * @throws */ public static List<Map<String,Object>> mergeList(){ //构建List集合1 List<Map<String,Object>> list1 = new ArrayList<>(); Map<String,Object> data=new HashMap<>(); data.put("userId","100001"); data.put("userName","唐僧"); list1.add(data); data=new HashMap<>(); data.put("userId","100002"); data.put("userName","八戒"); list1.add(data); data=new HashMap<>(); data.put("userId","100003"); data.put("userName","悟空"); list1.add(data); data=new HashMap<>(); data.put("userId","100004"); data.put("userName","沙僧"); list1.add(data); //构建List集合2 List<Map<String,Object>> list2 = new ArrayList<>(); data=new HashMap<>(); data.put("userId","100001"); data.put("gender","男"); data.put("age",20); list2.add(data); data=new HashMap<>(); data.put("userId","100002"); data.put("gender","雄"); data.put("age",1000); list2.add(data); data=new HashMap<>(); data.put("userId","100003"); data.put("gender","雄"); data.put("age",600); list2.add(data); data=new HashMap<>(); data.put("userId","100004"); data.put("gender","男"); data.put("age",800); list2.add(data); //使用stream流把list1和list2根据属性userId合并一个list集合 List<Map<String, Object>> list = list1.stream().map(m -> { list2.stream().filter(m2-> Objects.equals(m.get("userId"),m2.get("userId"))).forEach(m2-> { m.put("gender",m2.get("gender")); m.put("age",m2.get("age")); }); return m; }).collect(Collectors.toList()); for(Map<String, Object> map:list){ System.out.println(map.toString()); } return list; } }
合并运行结果:
示例2:java8 合并两个 list<T>
java8 合并两个 list<T>, 并将tickeId相同的所有属性合并到一个T中
list1中对象的属性:ticketId、ticketName
list2中对象的属性:ticketId、saleNum、batchAvailableNum
最总集合中对象的属性:ticketId、ticketName、saleNum、batchAvailableNumimport java.util.*; import java.util.stream.Collectors; /** * @author qzz */ public class ListTest1 { public static void main(String[] args) { mergeList(); } /** * @Description: 合并两个list<Ticket>,并将ticketId相同的其它属性合并 * @Title: mergeList * @param: @return * @return: List<Ticket> * @throws */ public static List<Ticket> mergeList(){ //构建List集合1 List<Ticket> list1 = new ArrayList<>(); Ticket data=new Ticket(); data.setTicketId("100001"); data.setTicketName("唐僧"); list1.add(data); data=new Ticket(); data.setTicketId("100002"); data.setTicketName("八戒"); list1.add(data); data=new Ticket(); data.setTicketId("100003"); data.setTicketName("悟空"); list1.add(data); data=new Ticket(); data.setTicketId("100004"); data.setTicketName("沙僧"); list1.add(data); //构建List集合2 List<Ticket> list2 = new ArrayList<>(); data=new Ticket(); data.setTicketId("100001"); data.setSaleNum("20"); data.setBatchAvailableNum("10"); list2.add(data); data=new Ticket(); data.setTicketId("100001"); data.setSaleNum("20"); data.setBatchAvailableNum("10"); list2.add(data); data=new Ticket(); data.setTicketId("100002"); data.setSaleNum("1000"); data.setBatchAvailableNum("600"); list2.add(data); data=new Ticket(); data.setTicketId("100003"); data.setSaleNum("600"); data.setBatchAvailableNum("100"); list2.add(data); data=new Ticket(); data.setTicketId("100004"); data.setSaleNum("800"); data.setBatchAvailableNum("300"); list2.add(data); //使用stream流把list1和list2根据属性ticketId合并一个list集合 List<Ticket> list = list1.stream().map(m -> { list2.stream().filter(m2-> Objects.equals(m.getTicketId(),m2.getTicketId())).forEach(m2-> { m.setSaleNum(m2.getSaleNum()); m.setBatchAvailableNum(m2.getBatchAvailableNum()); }); return m; }).collect(Collectors.toList()); for(Ticket ticket:list){ System.out.println(ticket.getTicketId()+","+ticket.getTicketName()+","+ticket.getSaleNum()+","+ticket.getBatchAvailableNum()); } return list; } }
合并运行结果:
示例3:java8 合并两个 list<T>,集合个数前者小于后者,要后者
list1中对象的属性:ticketId、ticketName
list2中对象的属性:ticketId、batchId
最总集合中对象的属性:ticketId、ticketName、batchId
list1:
ticketId:10001 , ticketName:唐僧
ticketId:10002 , ticketName:八戒
list2:
ticketId:10001 , batchId:1
ticketId:10001 , batchId:2
ticketId:10002 , batchId:1
ticketId:10002 , batchId:2
ticketId:10003 , batchId:2
想要的结果:list1合并到 list 2
ticketId:10001 , ticketName:唐僧,batchId:1
ticketId:10001 , ticketName:唐僧,batchId:2
ticketId:10002 , ticketName:八戒,batchId:1
ticketId:10002 , ticketName:八戒,batchId:2
ticketId:10003 , ticketName:八戒,batchId:2代码实现:
import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * @author qzz */ public class ListTest2 { public static void main(String[] args) { mergeList(); } /** * @Description: 合并两个list<map>,并将userId相同的其它属性合并 * @Title: mergeList * @param: @return * @return: List<Map<String,Object>> * @throws */ public static List<Ticket> mergeList(){ List<Ticket> list1 = new ArrayList<>(); Ticket data=new Ticket(); data.setTicketId("100001"); data.setTicketName("唐僧"); list1.add(data); data=new Ticket(); data.setTicketId("100002"); data.setTicketName("八戒"); list1.add(data); List<Ticket> list2 = new ArrayList<>(); data=new Ticket(); data.setTicketId("100001"); data.setBatchId("1"); list2.add(data); data=new Ticket(); data.setTicketId("100001"); data.setBatchId("2"); list2.add(data); data=new Ticket(); data.setTicketId("100002"); data.setBatchId("1"); list2.add(data); data=new Ticket(); data.setTicketId("100002"); data.setBatchId("2"); list2.add(data); data=new Ticket(); data.setTicketId("100002"); data.setBatchId("3"); list2.add(data); //使用stream流把list1合并到list2集合中,根据ticketId属性 List<Ticket> list = list2.stream().map(m -> { list1.stream().filter(m2-> Objects.equals(m.getTicketId(),m2.getTicketId())).forEach(m2-> { m.setTicketId(m2.getTicketId()); m.setTicketName(m2.getTicketName()); }); return m; }).collect(Collectors.toList()); for(Ticket ticket:list){ System.out.println(ticket.getTicketId()+","+ticket.getTicketName()+","+ticket.getBatchId()); } return list; } }
合并运行结果:
示例4:java8 合并两个 list<T>,集合个数前者大于后者,要后者
list1中对象的属性:ticketId、ticketName
list2中对象的属性:ticketId、batchId
最总集合中对象的属性:ticketId、ticketName、batchId
list1:
ticketId:10001 , ticketName:唐僧
ticketId:10002 , ticketName:八戒
list2:
ticketId:10001 , batchId:1
ticketId:10001 , batchId:2想要的结果:list1合并到 list 2,过滤掉batch不存在的数据
ticketId:10001 , ticketName:唐僧,batchId:1
ticketId:10001 , ticketName:唐僧,batchId:2代码实现:
import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * @author qzz */ public class ListTest3 { public static void main(String[] args) { mergeList(); } /** * @Description: 合并两个list<map>,并将userId相同的其它属性合并 * @Title: mergeList * @param: @return * @return: List<Map<String,Object>> * @throws */ public static List<Ticket> mergeList(){ List<Ticket> list1 = new ArrayList<>(); Ticket data=new Ticket(); data.setTicketId("100001"); data.setTicketName("唐僧"); list1.add(data); data=new Ticket(); data.setTicketId("100002"); data.setTicketName("八戒"); list1.add(data); List<Ticket> list2 = new ArrayList<>(); data=new Ticket(); data.setTicketId("100001"); data.setBatchId("1"); list2.add(data); data=new Ticket(); data.setTicketId("100001"); data.setBatchId("2"); list2.add(data); // data=new Ticket(); // data.setTicketId("100002"); // data.setBatchId("1"); // list2.add(data); // // data=new Ticket(); // data.setTicketId("100002"); // data.setBatchId("2"); // list2.add(data); // // data=new Ticket(); // data.setTicketId("100002"); // data.setBatchId("3"); // list2.add(data); //使用stream流把list1合并到list2集合中,根据ticketId属性 List<Ticket> list = list2.stream().map(m -> { list1.stream().filter(m2-> Objects.equals(m.getTicketId(),m2.getTicketId())).forEach(m2-> { m.setTicketId(m2.getTicketId()); m.setTicketName(m2.getTicketName()); }); return m; }).collect(Collectors.toList()); for(Ticket ticket:list){ System.out.println(ticket.getTicketId()+","+ticket.getTicketName()+","+ticket.getBatchId()); } return list; } }
合并运行结果:
延申:一个list 集合合并去重求和
使用stream实现list中对象属性的合并(去重并求和)
说明:
需要对一个List中的对象进行唯一值属性去重,属性求和,对象假设为Student,有id、nums、sums三个属性,其中id表示唯一值,需要nums与sums进行求和,并最后保持一份。
例如说:(“s1”, 1, 1),(“s1”,2,3),(“s2”,3,5), 求和并去重的话,就是(“s1”, 3, 4),(“s2”,3,5)对象属性:
/** * @author qzz */ public class Student { private String id; private int nums; private int sums; public String getId() { return id; } public void setId(String id) { this.id = id; } public int getNums() { return nums; } public void setNums(int nums) { this.nums = nums; } public int getSums() { return sums; } public void setSums(int sums) { this.sums = sums; } }
代码实现:
import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; /** * @author qzz */ public class StudentList { public static void main(String[] args) { List<Student> list = new ArrayList<>(); Student s1 = new Student(); s1.setId("s1"); s1.setNums(1); s1.setSums(1); list.add(s1); s1 = new Student(); s1.setId("s1"); s1.setNums(2); s1.setSums(3); list.add(s1); s1 = new Student(); s1.setId("s2"); s1.setNums(3); s1.setSums(5); list.add(s1); //合并去重求和 List<Student> result = merge(list); result.stream().forEach(e->{ System.out.println("id:"+e.getId()+",nums:"+e.getNums()+",sums:"+e.getSums()); }); } /** * 将id进行合并nums, sums 相加道回合并后的集合使用Java8的流进行处理 * @return */ public static List<Student> merge(List<Student> list){ List<Student> result = list.stream() .collect(Collectors.toMap(Student::getId, a->a,(o1,o2)->{ o1.setNums(o1.getNums()+o2.getNums()); o1.setSums(o1.getSums()+o2.getSums()); return o1; })).values().stream().collect(Collectors.toList()); return result; } }
运行结果:
-
Java LIst集合全解
2021-05-08 08:40:23集合的优势: (1)数组存储的不足与缺陷: 长度开始必须执行,而且一旦指定,无法修改 ...Collection接口有两个重要的子接口List、Set,他们的实现子类都是单列集合 Map接口的实现子类是双列集合,存放K-集合的优势:
(1)数组存储的不足与缺陷:
- 长度开始必须执行,而且一旦指定,无法修改
- 保存的必须为同一类型的元素
- 使用数组进行增加/删除操作比较麻烦
(2)集合的好处:
- 可以动态保存多个对象,使用方便
- 提供了一系列方便的操作对象的方法,如add、remove、set、get等
- 使用集合增加/删除较方便
集合的框架图 (重要)
集合主要是两组:单列集合、双列集合
Collection接口有两个重要的子接口List、Set,他们的实现子类都是单列集合
Map接口的实现子类是双列集合,存放K-V
Collection 接口和常用方法
1、Collection接口实现类的特点:
public interface Collection<E> extends Iterable<E>
1)Collection实现子类可以存放多个元素,每个元素可以是Object
2)有些Collection的实现类,可以存放重复的元素,有些不可以
3)有些Collection的实现类,可以是有序的(List), 有些也是无序的(Set)
4)Collection接口没有直接的实现子类,是通过他的子接口Set和List来实现的
2、Collection接口的常用方法,以实现子类ArrayList来演示:
public class T { public static void main(String[] args) { List list = new ArrayList(); //add添加元素 list.add("jack"); list.add(10); list.add(true); System.out.println("list = " + list); //remove 删除指定元素 //list.remove(0); //删除第一个元素 list.remove(true); //contains查找元素是否存在 System.out.println(list.contains("jack")); //size:获取元素个数 System.out.println(list.size()); //isEmpty判断是否为空 System.out.println(list.isEmpty()); //clear 清空 list.clear(); System.out.println("list = " + list); //addAll添加多个元素 ArrayList list2 = new ArrayList(); list2.add("hlm"); list2.add("sgyy"); list.addAll(list2); System.out.println("list = " + list); //containsAll:判断多个元素是否存在 System.out.println(list.containsAll(list2)); //removeAll 删除多个元素 list.add("lz"); list.removeAll(list2); System.out.println("list = " + list); } }
3、Collection接口遍历元素方式:
(1)使用Iterator(迭代器):
- Iterator对象称为迭代器,主要用于遍历Collection集合中的元素
- 所有实现了Collection接口的集合类都有一个iterator()方法,用于返回一个实现了Iterator接口的对象,即可以返回一个迭代。
- Iterator结构如图所示
- Iterator仅用于遍历集合,Iterator本身不存放对象。
public class CollectionIterator { @SuppressWarnings({"all"}) public static void main(String[] args) { Collection col = new ArrayList(); col.add(new Book("三国演义", "罗贯中", 10.1)); col.add(new Book("小李飞刀", "古龙", 5.1)); col.add(new Book("三红楼梦", "曹雪芹", 34.6)); // System.out.println("col : " + col); // 遍历集合: //1、 先得到col对应的迭代器 Iterator iterator = col.iterator(); //2、使用while循环遍历 while(iterator.hasNext()) { //返回下一个元素, 类型是Object Object obj = iterator.next(); System.out.println("obj=" + obj); } //快捷键,快速生成while =》 itit } } class Book { private String name; private String author; private double price; public Book(String name, String author, double price) { this.name = name; this.author = author; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", author='" + author + '\'' + ", price=" + price + '}'; } }
(2)增强for循环(底层是iterator)
基本语法:
for(元素类型 元素名: 集合名/数组名){ 访问元素; }
List 接口和常用方法
1、List接口的特点
- List集合类中元素有序(添加顺序和取出顺序一致),且可重复
- List集合中的每个元素都有其对应的顺序索引,即支持索引
- List容器中的元素都对应一个整数型的序号记载其在容器中的位置,额可以根据序号存取容器中的元素
- JDK API中List接口的实现类非常多,常用的有ArrayList、Set、Vector
2、List接口常用方法
public class ListMethod { @SuppressWarnings({"all"}) public static void main(String[] args) { List list = new ArrayList(); list.add("张三丰"); list.add("贾宝玉"); // void add(int index, Object ele):在index位置插入ele元素 //在index = 1的位置插入一个对象 list.add(1, "韩顺平"); System.out.println("list=" + list); // boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来 List list2 = new ArrayList(); list2.add("jack"); list2.add("tom"); list.addAll(1, list2); System.out.println("list=" + list); // Object get(int index):获取指定index位置的元素 //说过 // int indexOf(Object obj):返回obj在集合中首次出现的位置 System.out.println(list.indexOf("tom"));//2 // int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置 list.add("韩顺平"); System.out.println("list=" + list); System.out.println(list.lastIndexOf("韩顺平")); // Object remove(int index):移除指定index位置的元素,并返回此元素 list.remove(0); System.out.println("list=" + list); // Object set(int index, Object ele):设置指定index位置的元素为ele , 相当于是替换. list.set(1, "玛丽"); System.out.println("list=" + list); // List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合 // 注意返回的子集合 fromIndex <= subList < toIndex List returnlist = list.subList(0, 2); System.out.println("returnlist=" + returnlist); } }
3、List三种遍历方式(ArrayList、LinkedList,Vector):
ArrayList底层结构和源码分析
1、注意事项:
- 允许存储所有元素,包括null,ArrayList可以加入一个或者多个null
- ArrayList是由数组来实现数据存储的
- ArrayList基本等同于Vector,除了ArrayList是线程不安全的(源码中没有synchronized关键字,执行效率高),在多线程的情况下不建议使用ArrayList
2、ArrayList底层操作机制源码分析
- ArrayList中维护了一个Object类型的数组elementData:
transient Object[] elementData;//transient关键字表示,该属性不会被序列化
- 当创建ArrayList对象的时候,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容elementData为10,如需再次扩容, 则扩容elementData1.5倍
- 如果使用的是指定大小的构造器,则初始化elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍
(1)无参与有参构造器创建和使用ArrayList源码分析:
Vector底层结构和源码分析
1、注意事项:
2、Vector和ArrayList比较:
3、Vector底层扩容:
public class Vector_ { public static void main(String[] args) { //无参构造器 //有参数的构造 Vector vector = new Vector(8); for (int i = 0; i < 10; i++) { vector.add(i); } vector.add(100); System.out.println("vector=" + vector); //老韩解读源码 //1. new Vector() 底层 /* public Vector() { this(10); } 补充:如果是 Vector vector = new Vector(8); 走的方法: public Vector(int initialCapacity) { this(initialCapacity, 0); } 2. vector.add(i) 2.1 //下面这个方法就添加数据到vector集合 public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; } 2.2 //确定是否需要扩容 条件 : minCapacity - elementData.length>0 private void ensureCapacityHelper(int minCapacity) { // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } 2.3 //如果 需要的数组大小 不够用,就扩容 , 扩容的算法 //newCapacity = oldCapacity + ((capacityIncrement > 0) ? // capacityIncrement : oldCapacity); //就是扩容两倍. private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); } */ } }
LinkedList:
LinkedList说明:
- LinkedList底层实现了双向链表和双端队列的特点
- 可以添加任意元素(可以重复), 包括null
- 线程不安全,没有实现同步
LinkedList底层机制
- LinkedList底层维护了一个双向链表
- LinkedList中维护了两个属性first和last分别指向首节点和尾节点
- 每个节点(Node对象),里面又维护了prev、next、item三个属性,其中prev指向前一个,通过next指向后一个节点,最终实现双向链表
- 所以LinkedList的元素添加和删除,不是通过数组实现的,相对来说效率较高
LinkedList基本操作:
public class LinkedListCRUD { public static void main(String[] args) { LinkedList linkedList = new LinkedList(); linkedList.add(1); linkedList.add(2); linkedList.add(3); System.out.println("linkedList=" + linkedList); //演示一个删除结点的 linkedList.remove(); // 这里默认删除的是第一个结点 //linkedList.remove(2); //指定删除第几个元素 System.out.println("linkedList=" + linkedList); //修改某个结点对象,按照索引 linkedList.set(1, 999); System.out.println("linkedList=" + linkedList); //得到某个结点对象 //get(1) 是得到双向链表的第二个对象 Object o = linkedList.get(1); System.out.println(o);//999 //因为LinkedList 是 实现了List接口, 遍历方式 System.out.println("===LinkeList遍历迭代器===="); Iterator iterator = linkedList.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println("next=" + next); } System.out.println("===LinkeList遍历增强for===="); for (Object o1 : linkedList) { System.out.println("o1=" + o1); } System.out.println("===LinkeList遍历普通for===="); for (int i = 0; i < linkedList.size(); i++) { System.out.println(linkedList.get(i)); } //老韩源码阅读. /* 1. LinkedList linkedList = new LinkedList(); public LinkedList() {} 2. 这时 linkeList 的属性 first = null last = null 3. 执行 先进行装箱 再调用添加, public boolean add(E e) { linkLast(e); return true; } 4.将新的结点,加入到双向链表的最后 Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; } */ /* 老韩读源码 linkedList.remove(); // 这里默认删除的是第一个结点 1. 执行 removeFirst public E remove() { return removeFirst(); } 2. 执行 public E removeFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return unlinkFirst(f); } 3. 执行 unlinkFirst, 将 f 指向的双向链表的第一个结点拿掉 private E unlinkFirst(Node<E> f) { // assert f == first && f != null; final E element = f.item; final Node<E> next = f.next; f.item = null; f.next = null; // help GC first = next; if (next == null) last = null; else next.prev = null; size--; modCount++; return element; } */ } }
ArrayList(线程不安全)和LinkedList(线程不安全)的比较:
如何选择ArrayList和LinkedList:
1)如果改查操作多,选择ArrayList
2)如果增删操作多,选择LinkedList
3)一般来说,在程序中,80%-90%都是查询,因此大部分情况下都会选择ArrayList
4)在一个项目中,根据业务灵活选择。
-
Map集合和List集合总结
2019-05-27 17:32:15Map集合和List集合哪个效率更高 List接口 List集合是一个元素有序(存储有序)、可重复的集合,集合中的每个元素都有对应的索引,以便于查询和修改,List集合是允许存储null值的。 List集合可重复原因,请看源码: ... -
List集合如何分页(List集合转Page分页)
2021-09-29 16:25:14写在前头 这段时间写了一个小需求,做page页筛选功能,但这个筛选项有两个条件,且是多选,那就不得不用list集合来做处理,再转page 下面的list转page方法,可以直接复制拿来用: /** * 分页函数 * @author ... -
【集合】遍历 List 集合的几种方式
2021-06-06 19:23:181. 初始化 List 集合 List<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); 2. 遍历 方式一:for循环 最基础的遍历方式:for循环,指定下标位置,使用 List 集合的 ... -
Java中List集合的遍历
2021-11-12 17:36:30List集合在Java日常开发中是必不可少的,只要懂得运用各种各样的方法就可以大大提高我们开发的效率,适当活用各种方法才会使我们开发事半功倍。 本文总结了三种List集合的遍历方式,下面将依次进行介绍。 二、... -
Java List集合反转元素
2022-05-03 17:53:40想要将ArrayList集合的元素 1 2 3 反转成 3 2 1。使用 Collections.reverse(list) 。包在import java.util.Collections 如: List<Integer> list = new ArrayList<>(); Collections.reverse(list)... -
使用Mybatis将List集合数据存入数据库
2021-03-08 16:41:19**问题说明:**在我们实际的业务开发中,会有将Java中的集合数据存入数据库中,或者将数据库中的数据读取到List集合中返回的情况,例如,我们需要保存某个用户的爱好,按照我们以往的做法,我们可能在数据库定义... -
java 两个List集合各种情况对比处理
2021-03-04 04:51:08【java】【反射】反射实现判断发生了修改操作,判断两个对象是否发生属性值的变更,判断两个List集合内对象的属性值是否发生变更 java的反射实现: 判断发生了修改操作,判断两个对象是否发生属性值的变更,判断两个... -
遍历List集合的三种方法
2021-12-14 14:51:48遍历List集合的三种方法 List<String> list = new ArrayList<String>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); 方法一: 超级for循环遍历 for(String attribute : list) { System.out.... -
Json转List集合的方法
2022-01-20 11:19:39使用fastJson可以直接实现 String jsonStr = JSON.toJSONString(object);...List<VO> list = JSON.parseArray(json, VO.class); list.forEach( item -> { System.out.println(item.name); } ) -
向一个List集合中添加另一个List集合
2021-05-25 18:51:25向一个List集合中添加另一个List集合List List @Override public List<MetaUdResource> AllvalidMetaUdSourceLists() throws Exception { List<MetaUdResource> metaUdResources=... -
MyBatis 传入List集合作为条件查询数据
2021-01-27 16:35:53使用的是SSM框架,数据库是MySQL,做查询的时候传入List集合,使用SQL语句的in方式查询数据主要有两点问题:我的List集合是利用的另外一个语句查询出来的,传入参数是int类型,返回值是int类型的List集合:public ... -
Java中List集合判空
2022-02-09 19:03:591、如果想判断list是否为空,可以这么判断: if(null == list || list.size() ==0 ){ ...如果判断一个集合有无元素 建议用isEmpty()方法.比较符合逻辑用法。 3、list !=null 跟 ! list.isEmpty()有什么区别? -
SpringBoot中yml配置文件:定义list集合、数组及注意事项
2022-01-19 00:46:54定义list集合不能用@value注解来获取list集合的所有值,需要定义一个配置类bean,然后使用 @ConfigurationProperties注解来获取list集合值,做法如下: @Data @Component @ConfigurationProperties(prefix = ... -
Java删除List集合中元素的方法
2021-11-12 16:05:11先初始化一个List集合 List list = new ArrayList(){ {add(1); add(2); add(3); }}; 1、增强for循环 错误示范 for (Integer i : list) { list.remove(i); } 这样做会抛出异常,因为不允许在元素被使用的时候同时被... -
java 把一个LIst集合分割成多个集合
2021-12-31 10:30:49* Description: Java8 Stream分割list集合,此函数的作用是,传入指定的List集合和指定的数量,输出结果是新集合,新集合中包含的在若干个子集合,每个子集合的长度是splitSize * @param list 传入的list集合 * @... -
List集合数据移除(List.subList.clear)
2020-10-21 23:11:52List集合数据移除(List.subList.clear) 这两天遇到这么一个问题:一个集合的数据当作参数传入,现在分段使用这个集合的数据,使用完的数据需要在这个集合中被移除,方便获取第二段的数据。 假设:一个集合的数据长度... -
java8 list取属性值集合 java8从list集合中取出某一属性的值的集合案例
2021-03-24 01:05:39想了解java8从list集合中取出某一属性的值的集合案例的相关内容吗,*饼饼*在本文为您仔细讲解java8 list取属性值集合的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:java8,list集合,属性值集合,下面大家... -
【Flutter】Dart 数据类型 List 集合类型 ( 定义集合 | 初始化 | 泛型用法 | 初始化后添加元素 | 集合生成...
2020-03-18 21:05:30I . 定义集合并初始化 II . 集合泛型用法 III . 集合添加元素 IV . 集合生成函数 V . 集合遍历 VI . 集合示例代码 -
将JSON数组转化为List集合
2022-04-12 20:29:12假如我们向redis中存放了一个JSON数组,从中获取的时候需要将JSON数组转化为List集合,然后将List对象返回给前端。 1.引入hutool和fastjson依赖 <!--hutool--> <dependency> <groupId>... -
Java对List集合排序
2021-06-08 10:38:301.单属性变量集合排序,如LIst<Integer> List<Integer> intList = new ArrayList<>(); intList.add(54); intList.add(7674); intList.add(636); intList.add(4325); intList.add(21); ... -
List集合&数据结构
2020-06-16 14:09:211.Collection集合 1.1集合的体系结构 集合类的特点 ...JDK不提供此接口的任何实现,它提供更具体的子接口(Set和List)实现 Collection集合基本使用 public class CollectionDemo1{ public stat -
java中list集合对sort的使用方法
2020-04-12 18:42:38List集合的排序: java提供了两种排序方式,分别是Collections.sort(List)和Collections.sort(List,Commparator),下面就这两种方法的使用做详细的说明: 方法一:Collections.sort(List) 这个方法有分两种情况:1、... -
java中List集合三种获取集合元素方式
2021-08-20 08:16:00java中List集合三种获取集合元素方式 1.for 2.迭代器 3.增强for循环 List集合特点 List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法,... -
如何把字符串转化为 List 集合
2021-09-09 17:45:30Java中,我们有时需要对现有的字符串进行切割并转化成一个List集合。 Java.lang 包中的 String.split() 方法可对现有的字符串进行切割,并返回一个字符串数组。