Lambda Optional Checking value presence and conditional action
SysUser  user  =  new  SysUser ();SysDept  dept  =  new  SysDept ();dept.setDeptName("development" ); user.setDept(dept); Optional<String> optional = Optional.ofNullable(user)     .map(SysUser::getDept)     .map(SysDept::getDeptName); optional.ifPresent(System.out::println); String  deptName  =  optional.orElse("default" );String  deptName  =  optional.orElseGet(() -> "to get default" );optional.orElseThrow(() -> new  RuntimeException ("to throw exception" )); String  deptName  =  Optional.ofNullable(user)    .map(SysUser::getDept)     .map(SysDept::getDeptName)     .orElse("defaultDept" ); 
 
Stream Create Streams 
Using collection 
 
 
Create a stream from specified values 
 
Stream.of(T…t)
Stream<Integer> stream = Stream.of(1 , 2 , 3 , 4 , 5 ); 
 
Create a stream from an array 
 
Arrays.stream(arr); Arrays.stream(arr, from, to) Stream.of(arr); 
 
Create an empty stream using Stream.empty() 
 
The empty() method is used upon creation to avoid returning null for streams with no element.
Stream<String> streamOfArray             = Stream.empty(); 
 
Using Stream.builder() 
 
Stream.Builder<String> builder = Stream.builder(); Stream<String> stream = builder.add("a" ).add("b" ).add("c" ).build(); 
 
Create an infinite Stream using Stream.iterate() 
 
Stream.iterate(seedValue, (Integer n) -> n * n)             .limit(limitTerms)             .forEach(System.out::println); 
 
Create an infinite Stream using Stream.generate() 
 
Stream.generate(Math::random)             .limit(limitTerms)             .forEach(System.out::println); 
 
Create stream from Iterator 
 
Iterator<String> iterator = Arrays.asList("a" , "b" , "c" ).iterator(); Spliterator<T> spitr = Spliterators.spliteratorUnknownSize(iterator, Spliterator.NONNULL); Stream<T> stream = StreamSupport.stream(spitr, false ); 
 
Create stream from Iterable 
 
Iterable<String> iterable = Arrays.asList("a" , "b" , "c" ); Stream<T> stream = StreamSupport.stream(iterable.spliterator(), false ); 
 
Collect streams List<Integer> numList = Stream.of(1 , 2 , 3 ).toList(); System.out.println(numList); 
 
List<Integer> numList = Stream.of(1 , 2 , 3 ).collect(Collectors.toList()); System.out.println(numList); 
 
Print streams Stream.of(1 , 2 , 3 ).forEach(System.out::println); 
 
Collections Construction Collection Element Type Conversion String list to Object list 
by assignment
String[] stringArray = new  String [10 ]; Object[] objectArray = stringArray; 
 
by contructor
List<String> stringList = new  ArrayList <>(); List<Object> objectList = new  ArrayList <>(stringList); Set<String> stringSet = new  HashSet <>(); Set<Object> objectSet = new  HashSet <>(stringSet); 
 
by for loop
Map<String, List<String>> multiStringValueMap = new  HashMap <>(); multiStringValueMap.put("key1" , Arrays.asList("taogen" , "taogen2" )); multiStringValueMap.put(null , Arrays.asList(null , null , null )); multiStringValueMap.put("testNullValue" , null ); Map<String, List<Object>> multiObjectValueMap = new  HashMap <>(); multiStringValueMap.forEach((key, value) -> {     List<Object> objectList = null ;     if  (value != null ) {         objectList = value.stream()             .collect(Collectors.toList());     }     multiObjectValueMap.put(key, objectList); }); System.out.println(multiObjectValueMap); 
 
Object list to String list 
by Java Stream
List<Object> objectList = new  ArrayList <>(); List<String> stringList = objectList.stream()     .map(object -> Objects.toString(object, null ))     .collect(Collectors.toList()); for  (Object s : objectList) {    System.out.println(s + ", isNull: "  + Objects.isNull(s)); } 
 
by for loop
List<Object> objectList = new  ArrayList <>(); List<String> stringList = new  ArrayList <>(objectList.size()); for  (Object object : objectList) {    stringList.add(Objects.toString(object, null )); } for  (Object s : objectList) {    System.out.println(s + ", isNull: "  + Objects.isNull(s)); } 
 
Map<String, List<Object>> multiObjectValueMap = new  HashMap <>(); multiObjectValueMap.put("key1" , Arrays.asList(1 , 2 , 3 )); multiObjectValueMap.put(null , Arrays.asList(null , null , null )); multiObjectValueMap.put("testNullValue" , null ); multiObjectValueMap.put("key2" , Arrays.asList("taogen" , "taogen2" )); Map<String, List<String>> multiStringValueMap = new  HashMap <>(); multiObjectValueMap.forEach((key, value) -> {     List<String> stringList = null ;     if  (value != null ) {         stringList = value.stream()             .map(object -> Objects.toString(object, null ))             .collect(Collectors.toList());     }     multiStringValueMap.put(key, stringList); }); System.out.println(multiStringValueMap); 
 
Warning: to convert a object value to a string value you can use Objects.toString(object) or object != null ? object.toString() : null. but not String.valueOf() and toString(). The result of String.valueOf(null) is “null” not null. If the object value is null, calling toString() will occur NullPointerExcpetion.
Collection Conversion To Array 
Object list to array
User[] users = userList.toArray(new  User [0 ]); Integer[] integers = integerList.toArray(new  Integer [0 ]); String[] strings = stringList.toArray(new  String [0 ]); 
 
User[] users = userList.stream().toArray(User[]::new ); Integer[] integers = integerList.stream().toArray(Integer[]::new ); String[] strings = stringList.stream().toArray(String[]::new ); String[] strings = stringList.toArray(String[]::new ); 
 
int [] array = new  int [list.size()];for (int  i  =  0 ; i < list.size(); i++) array[i] = list.get(i);
 
To ArrayList 
Convert Set to ArrayList
Set<String> set = new  HashSet (); ArrayList<String> list = new  ArrayList (set); 
 
 
List<String> list = set.stream().collect(Collectors.toList()); 
 
var  list  =  List.copyOf(set);
 
Convert Wrapper Type Array to ArrayList
String[] array = new  String [10 ]; Integer[] array2 = new  Integer [10 ]; ArrayList<String> list = new  ArrayList (Arrays.asList(array)); 
 
Convert Primitive Array to ArrayList
int [] input = new  int []{1 ,2 ,3 ,4 };List<Integer> output = Arrays.stream(input).boxed().collect(Collectors.toList()); 
 
int [] input = new  int []{1 ,2 ,3 ,4 };List<Integer> output = IntStream.of(input).boxed().collect(Collectors.toList()); 
 
To Set 
Convert ArrayList to Set
ArrayList<String> list = new  ArrayList (); Set<String> set = new  HashSet (list); 
 
 
Set<String> set = list.stream().collect(Collectors.toSet()); 
 
var  set  =  Set.copyOf(list);
 
Convert Wrapper Type Array to Set
String[] array = new  String [10 ]; Set<String> set = new  HashSet (Arrays.asList(array)); 
 
Convert other set classes
list.stream().collect(Collectors.toCollection(LinkedHashSet::new )) 
 
To Map 
Convert Object Fields of List to Map
List<SysUser> sysUserList = getUserList(); Map<Long, String> idToName = sysUserList.stream()     .collect(Collectors.toMap(SysUser::getId, SysUser::getName)); Map<Long, String> idToName = sysUserList.stream()     .collect(Collectors.toMap(item -> item.getId(), item -> item.getName())); 
 
List<IdName> list = getIdNameList(); Map<Long, IdName> idToObjMap = list.stream()     .collect(Collectors.toMap(IdName::getId, Function.identity())); Map<Long, IdName> idToObjMap = list.stream()     .collect(Collectors.toMap(item -> item.getId(), item -> item)); 
 
Convert to other map classes
List<IdName> idNameList = new  ArrayList <>(); Map<Integer,String> idToNameMap = idNameList.stream().collect(Collectors.toMap(IdName::getId, IdName::getName, (o1, o2) -> o1, TreeMap::new )); 
 
List<IdName> idNameList = new  ArrayList <>(); idNameList.stream().collect(Collectors.toConcurrentMap(IdName::getId, IdName::getName)); 
 
Merge Merge byte[] array 
use System.arraycopy
byte [] one = getBytesForOne();byte [] two = getBytesForTwo();byte [] combined = new  byte [one.length + two.length];System.arraycopy(one,0 ,combined,0          ,one.length); System.arraycopy(two,0 ,combined,one.length,two.length); 
 
Use List
byte [] one = getBytesForOne();byte [] two = getBytesForTwo();List<Byte> list = new  ArrayList <Byte>(Arrays.<Byte>asList(one)); list.addAll(Arrays.<Byte>asList(two)); byte [] combined = list.toArray(new  byte [list.size()]);
 
Use ByteBuffer
byte [] allByteArray = new  byte [one.length + two.length + three.length];ByteBuffer  buff  =  ByteBuffer.wrap(allByteArray);buff.put(one); buff.put(two); buff.put(three); byte [] combined = buff.array();
 
Convert List to Tree  convert list to tree with parentId
The data
[ { 	id:  1 ,  	name:  "a" ,  	prarentId:  0  } , { 	id:  10 ,  	name:  "b" ,  	prarentId:  1  } , { 	id:  2 ,  	name:  "c" ,  	prarentId:  0  } ] 
 
The process of conversion
1. original list a b c 2. link children and mark first level nodes *a -> b b *c 3. get first level nodes a -> b c 
 
Implementation
@Data public  class  IdName  {    private  String id;     private  String name;     private  String parentId;     private  List<IdName> children;     public  IdName (String id, String name, String parentId)  {         this .id = id;         this .name = name;         this .parentId = parentId;     }     private  void  putChildren (IdName idName)  {         if  (this .children == null ) {             this .children = new  ArrayList <>();         }         this .children.add(idName);     }     public  static  List<IdName> convertListToTree (List<IdName> list)  {         if  (list == null  || list.isEmpty()) {             return  Collections.emptyList();         }         Map<String, IdName> map = list.stream()             .collect(Collectors.toMap(IdName::getId, Function.identity()));         List<IdName> firstLevelNodeList = new  ArrayList <>();         for  (IdName idName : list) {             IdName  parent  =  map.get(String.valueOf(idName.getParentId()));             if  (parent != null ) {                 parent.putChildren(idName);             } else  {                 firstLevelNodeList.add(idName);             }         }         return  firstLevelNodeList;     } } public  static  void  main (String[] args)  {    List<IdName> idNames = new  ArrayList <>();     idNames.add(new  IdName ("1" , "Jack" , "0" ));     idNames.add(new  IdName ("2" , "Tom" , "0" ));     idNames.add(new  IdName ("3" , "Jerry" , "1" ));     System.out.println(IdName.convertListToTree(idNames)); } 
 
Multiple level data is in multiple tables
public  List<AreaVo> getAreaVoList ()  {    List<Province> provinces = iProvinceService.list(         new  LambdaQueryWrapper <Province>()         .select(Province::getId, Province::getName, Province::getCode));     List<City> cities = iCityService.list(         new  LambdaQueryWrapper <City>()         .select(City::getId, City::getName, City::getCode, City::getProvinceCode));     List<County> counties = iCountyService.list(         new  LambdaQueryWrapper <County>()         .select(County::getId, County::getName, County::getCode, County::getCityCode));     List<AreaVo> resultList = new  ArrayList <>();     resultList.addAll(AreaVo.fromProvince(provinces));     resultList.addAll(AreaVo.fromCity(cities));     resultList.addAll(AreaVo.fromCounty(counties));     return  AreaVo.convertListToTree(resultList); } public  class  AreaVo  {    private  String label;     private  String value;     private  String parentId;     private  List<AreaVo> children;     public  static  List<AreaVo> fromProvince (List<Province> provinces)  {         if  (provinces == null  || provinces.isEmpty()) {             return  Collections.emptyList();         }         return  provinces.stream()             .map(item -> new  AreaVo (item.getName(), item.getCode(), "0" ))             .sorted(Comparator.comparing(AreaVo::getValue))             .collect(Collectors.toList());     }     public  static  List<AreaVo> convertListToTree (List<AreaVo> list)  {} } 
 
Find Path of Node In a Tree private  void  setAreaForList (List<User> records)  {    List<String> areaCodeList = records.stream()         .map(User::getAreaId)         .filter(Objects::nonNull)         .map(String::valueOf)         .collect(Collectors.toList());     List<AreaItem> areaItemList = iAreaService.findSelfAndAncestors(areaCodeList);     if  (areaItemList == null  || areaItemList.isEmpty()) {         return ;     }     Map<String, AreaItem> areaItemMap = areaItemList.stream()         .collect(Collectors.toMap(AreaItem::getCode, Function.identity()));     records.stream()         .filter(entity -> entity.getAreaId() != null )         .forEach(entity -> {             List<AreaItem> areaPath = new  ArrayList <>();             String  areaCode  =  entity.getAreaId().toString();             String  tempCode  =  areaCode;             AreaItem  areaItem  =  null ;             while  ((areaItem = areaItemMap.get(tempCode)) != null ) {                 areaPath.add(0 , areaItem);                 tempCode = areaItem.getParentCode();             }             if  (CollectionUtils.isEmpty(areaPath)) {                 return ;             }             int  totalLevel  =  2 ;             if  (areaPath.size() < totalLevel) {                 int  supplementSize  =  totalLevel - areaPath.size();                 for  (int  i  =  0 ; i < supplementSize; i++) {                     areaPath.add(null );                 }             } else  {                 areaPath = areaPath.subList(0 , totalLevel);             }             entity.setAreaPath(areaPath);             entity.setAreaArray(areaPath.stream()                                 .map(areaPathItem -> areaPathItem == null  ? null  : areaPathItem.getCode())                                 .collect(Collectors.toList()));         }); } 
 
Multiple level data is in multiple tables
public  List<AreaItem> findSelfAndAncestors (List<String> areaCodeList)  {    if  (CollectionUtils.isEmpty(areaCodeList)) {         return  Collections.emptyList();     }     List<String> tempCodeList = areaCodeList;     List<AreaItem> resultAreaList = new  ArrayList <>();     List<AreaCounty> countyList = iAreaCountyService.list(         new  LambdaQueryWrapper <AreaCounty>()         .select(AreaCounty::getCode, AreaCounty::getName, AreaCounty::getCityCode)         .in(AreaCounty::getCode, tempCodeList));     if  (!CollectionUtils.isEmpty(countyList)) {         AreaItem.fromAreaCounty(countyList)             .forEach(areaItem -> {                 resultAreaList.add(areaItem);                 areaItem.setLevel(3 );             });         tempCodeList = areaCodeList;          tempCodeList.addAll(countyList.stream()                             .map(AreaCounty::getCityCode)                             .collect(Collectors.toList()));     }     List<AreaCity> cityList = iAreaCityService.list(         new  LambdaQueryWrapper <AreaCity>()         .select(AreaCity::getCode, AreaCity::getName, AreaCity::getProvinceCode)         .in(AreaCity::getCode, tempCodeList));     if  (!CollectionUtils.isEmpty(cityList)) {         AreaItem.fromAreaCity(cityList)             .forEach(areaItem -> {                 resultAreaList.add(areaItem);                 areaItem.setLevel(2 );             });         tempCodeList = areaCodeList;         tempCodeList.addAll(cityList.stream()                             .map(AreaCity::getProvinceCode)                             .collect(Collectors.toList()));     }     List<AreaProvince> provinceList = iAreaProvinceService.list(         new  LambdaQueryWrapper <AreaProvince>()         .select(AreaProvince::getCode, AreaProvince::getName)         .in(AreaProvince::getCode, tempCodeList));     if  (!CollectionUtils.isEmpty(provinceList)) {         AreaItem.fromAreaProvince(provinceList)             .forEach(areaItem -> {                 resultAreaList.add(areaItem);                 areaItem.setLevel(1 );             });     }     return  resultAreaList; } 
 
Find Descendant Nodes in a Tree Find self and descendant list
private  List<User> findSelfAndDescendants (Integer parentId) {    List<User> resultList = new  ArrayList <>();     List<Integer> tempIds = new  ArrayList <>();     tempIds.add(parentId);     List<User> descendants = null ;     while  (!CollectionUtils.isEmpty(descendants = getListByIds(tempIds))) {         resultList.addAll(descendants);         tempIds.clear();         tempIds = descendants.stream().map(User::getId).collect(Collectors.toList());     }     return  resultList; } public  List<User> getListByIds (List<Integer> ids) {}
 
Find descendant list
private  List<User> findDescendants (Integer parentId) {    List<User> resultList = new  ArrayList <>();     List<Integer> tempIds = new  ArrayList <>();     tempIds.add(parentId);     List<User> descendants = null ;     while  (!CollectionUtils.isEmpty(descendants = getListByParentIds(tempIds))) {         resultList.addAll(descendants);         tempIds.clear();         tempIds = descendants.stream().map(User::getId).collect(Collectors.toList());     }     return  resultList; } public  List<User> getListByParentIds (List<Integer> tempIds) {}
 
Find self and descendant ids
private  List<Integer> findSelfAndDescendantIds (Integer parentId) {    List<Integer> resultIds = new  ArrayList <>();     resultIds.add(id);     List<Integer> tempIds = new  ArrayList <>();     tempIds.add(parentId);     List<Integer> childrenIds = null ;     while  (!CollectionUtils.isEmpty(childrenIds = getChildrenIdsByParentIds(tempIds))) {         resultIds.addAll(childrenIds);         tempIds.clear();         tempIds.addAll(childrenIds);     }     return  resultIds; } public  List<Integer> getChildrenIdsByParentIds (List<Integer> parentIds) {}
 
public  Set<Integer> getDescendantIds (Integer deptId)  {    List<Object> descendantIds = new  ArrayList <>();     List<Object> childIds = this .baseMapper.selectObjs(new  LambdaQueryWrapper <SysDept>()                                                             .select(SysDept::getDeptId)                                                             .eq(SysDept::getParentId, deptId));     while  (!CollectionUtils.isEmpty(childIds)) {         descendantIds.add(childIds);         childIds = this .baseMapper.selectObjs(new  LambdaQueryWrapper <SysDept>()                                                    .select(SysDept::getDeptId)                                                    .in(SysDept::getParentId, childIds));     }     return  descendantIds.stream()         .map(Objects::toString)         .filter(Objects::nonNull)         .map(Integer::valueOf)         .collect(Collectors.toSet()); } 
 
Operation Traversal Array Traversal
for (int i = 0; i < array.length; i++) {...} 
Arrays.stream(array).xxx 
 
List Traversal
for loop: for (int i = 0; i < list.size(); i++) {...} 
enhanced for loop: for (Object o : list) {...} 
iterator or listIterator 
list.forEach(comsumer...) 
list.stream().xxx 
 
Handling List piece by piece public  static  void  main (String[] args)  {    List<Integer> list = Arrays.asList(1 , 2 , 3 , 4 , 5 );     int  listSize  =  list.size();     int  handlingSize  =  3 ;     int  startIndex  =  0 ;     int  endIndex  =  handlingSize;     while  (startIndex < listSize) {         if  (endIndex > listSize) {             endIndex = listSize;         }         handleList(list, startIndex, endIndex);         startIndex = endIndex;         endIndex = startIndex + handlingSize;     } } private  static  void  handleList (List<Integer> list, int  start, int  end)  {    for  (int  i  =  start; i < end; i++) {         System.out.println(list.get(i));     } } 
 
Map Traversal
for (String key : map.keySet()) {...}
 
for (Map.entry entry : map.entrySet()) {...}
 
Iterator
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator(); while  (iterator.hasNext()) {    Map.Entry<String, Integer> entry = iterator.next();     System.out.println(entry.getKey() + ":"  + entry.getValue()); } 
 
 
map.forEach(biComsumer...)
map.forEach((k, v) -> System.out.println((k + ":"  + v))); 
 
 
map.entrySet().stream()
 
 
forEach() vs stream()
If you just want to consume list, you best to choose forEach(), else stream(). 
 
Print collections Array
int  a[] = new  int []{1 , 2 , 3 };System.out.println(Arrays.toString(a)); 
 
List, Set
System.out.println(list); System.out.println(set); 
 
Map
Map<String, Integer> map = new  HashMap <>(); map.put("a" , 1 ); map.put("b" , 2 ); System.out.println(Arrays.toString(map.entrySet().toArray()));  System.out.println(Arrays.asList(map.entrySet().toArray()));  System.out.println(Arrays.asList(map));  System.out.println(map.entrySet().stream().map(entry -> entry.getKey() + ": "  + entry.getValue()).collect(Collectors.joining(", " )));  
 
HttpServletRequest’s ParameterMap
System.out.println(map.keySet().stream().map(key -> key + ": "  + request.getParameter(key)).collect(Collectors.joining(", " ))); 
 
Join Use stream
List<String> names = Arrays.asList("Tom" , "Jack" , "Lucy" ); System.out.println(names.stream().map(Object::toString).collect(Collectors.joining("," ))); List<Integer> ids = Arrays.asList(1 , 2 , 3 ); System.out.println(ids.stream().map(Object::toString).collect(Collectors.joining("," ))); 
 
Use String.join()
List<String> names = Arrays.asList("Tom" , "Jack" , "Lucy" ); System.out.println(String.join("," , names)); 
 
Remove elements from collection List<Book> books = new ArrayList<Book>(); books.add(new Book(new ISBN("0-201-63361-2"))); books.add(new Book(new ISBN("0-201-63361-3"))); books.add(new Book(new ISBN("0-201-63361-4"))); 
 
Collect objects set and removeAll() 
 
Swap position of elements and create new collection copy from updated old collection. Don’t reorganize the collection. 
T(n) = O(n), S(n) = O(n) 
 
ISBN isbn = new ISBN("0-201-63361-2"); List<Book> found = new ArrayList<>(); for(Book book : books){     if(book.getIsbn().equals(isbn)){         found.add(book);     } } books.removeAll(found); 
 
1.2 Collect indexes and remove one by one
T(n) = O(n), S(n) = O(m * n) 
 
1.3 Collect objects set and remove one by one
T(n) = O(n), S(n) = O(m * n) 
 
Using iterator to remove in loop 
 
Iterator using the cursor variable to traverse collection and remove by index of collection. If you remove a element, the cursor will update correctly. Iterator like forEach, but it index is not from 0 to size-1 of collection. The every remove operations will creating a new collection that copy from updated old collection. 
T(n) = O(n), S(n) = O(m * n) 
 
ListIterator<Book> iter = books.listIterator(); while(iter.hasNext()){     if(iter.next().getIsbn().equals(isbn)){         iter.remove();     } } 
 
removeIf() method (JDK 8) 
 
Swap position of elements, set new size for collection, and set null for between new size to old size elements. 
T(n) = O(n), S(n) = O(1) 
 
ISBN other = new ISBN("0-201-63361-2"); books.removeIf(b -> b.getIsbn().equals(other)); 
 
Using filter of Stream API (JDK 8) 
 
Creating new collection. Traversing has no order. 
T(n) = O(n), S(n) = O(n) guess by “A stream does not store data and, in that sense, is not a data structure. It also never modifies the underlying data source.” 
 
ISBN other = new ISBN("0-201-63361-2"); List<Book> filtered = books.stream()                            .filter(b -> b.getIsbn().equals(other))                            .collect(Collectors.toList()); 
 
Recommend: removeIf() > stream().filter() or parallelStream()> Collect objects set and removeAll() > Using iterator, or Collect indexes and remove one by one, or Collect objects set and remove one by one.
Deduplication Deduplicate values 
Deduplicate values by stream distinct() 
 
List<Integer> list = Arrays.asList(1 , 2 , 3 , 2 , 3 , 4 ); list = list.stream().distinct().collect(Collectors.toList()); System.out.println(list); 
 
Deduplicate values by creating a set 
 
List<Integer> list = new  ArrayList <>(Arrays.asList(1 , 2 , 3 , 2 , 3 , 4 )); Set<Integer> set = new  LinkedHashSet <>(list); list.clear();  list.addAll(set); System.out.println(list); 
 
List<Integer> list = Arrays.asList(1 , 2 , 3 , 2 , 3 , 4 ); list = new  ArrayList <>(new  LinkedHashSet <>(list)); System.out.println(list); 
 
Deduplicate objects by property 
Deduplicate by streamList<User> list = list.stream().collect(Collectors.toMap(User::getName, Function.identity(), (p, q) -> p, LinkedHashMap::new )).values(); 
 
Deduplicate objects by removing in for loopList<User> userList = buildUserList(); System.out.println("Before: "  + userList); Iterator<User> i = userList.iterator(); while  (i.hasNext()) {    User  user  =  i.next();     if  (user.getUserName().contains("test" )) {         i.remove();     } } System.out.println("After: "  + userList); 
 
Deduplicate objects by finding duplicate objects and then removing all of it 
 
List<User> userList = buildUserList(); System.out.println("Before: "  + userList); List<User> toRemoveList = new  ArrayList <>(); for  (User user : userList) {    if  (user.getUserName().contains("test" )) {         toRemoveList.add(user);     } } userList.removeAll(toRemoveList); System.out.println("After: "  + userList); 
 
Only one consecutive repeated element is retained List<IdName> list = new  ArrayList <>(); list.add(new  IdName (1 , "a" )); list.add(new  IdName (2 , "a" )); list.add(new  IdName (3 , "a" )); list.add(new  IdName (4 , "b" )); list.add(new  IdName (5 , "b" )); list.add(new  IdName (6 , "c" )); List<Integer> indexToRemove = new  ArrayList <>(); for  (int  i  =  0 ; i < list.size(); i++) {	if  (i < list.size() - 1  && list.get(i).getName().equals(list.get(i + 1 ).getName())) { 		indexToRemove.add(i); 	} } for  (int  i  =  indexToRemove.size() - 1 ; i >= 0 ; i--) {	list.remove(indexToRemove.get(i).intValue()); } System.out.println(list); 
 
Output
[IdName(id=3, name=a), IdName(id=5, name=b), IdName(id=6, name=c)] 
 
Ordered Collections 
Sorted Collection Classes 
 
Inserted order Collection Classes 
 
LinkedList 
LinkedHashSet 
LinkedHashMap 
 
Sorting 
Using Collections.sort(list) to sort Comparable elements 
 
It uses merge sort. T(n) = O(log n)
sort(List<T> list) 
sort(List<T> list, Comparator c) 
 
Comparators
Comparator.naturalOrder() 
Comparator.comparing(Function f) 
Comparator.comparingInt(Function f) 
Collections.reverseOrder() 
Collections.reverseOrder(Comparator c) 
 
(o1, o2) -> o1.getType().compareTo(o2.getType()) equals Comparator.comparing(User::getType)
Multiple fields with comparator
Comparator<Employee> compareByFirstName = Comparator.comparing(Employee::getFirstName); Comparator<Employee> compareByLastName = Comparator.comparing(Employee::getLastName); Comparator<Employee> compareByFullName = compareByFirstName.thenComparing(compareByLastName); 
 
Comparator<Employee> compareByName = Comparator     .comparing(Employee::getFirstName)     .thenComparing(Employee::getLastName); 
 
Comparator<IdName> c = (o1, o2) -> {     int  i  =  o1.getFirstName().compareTo(o2.getFirstName());     if  (i != 0 ) {         return  i;     }     return  o1.getLastName().compareTo(o2.getLastName()); }; 
 
Comparators avoid NullPointerException
Comparator<Employee> compareByName = Comparator     .comparing(Employee::getFirstName, Comparator.nullsLast(Comparator.naturalOrder()))     .thenComparing(Employee::getLastName, Comparator.nullsLast(Comparator.naturalOrder())); 
 
Comparator<IdName> c = (o1, o2) -> {          if  (o1.getId() == null ) {         return  1 ;     } else  if  (o2.getId() == null ) {         return  -1 ;     }     int  i  =  o1.getId().compareTo(o2.getId());     if  (i != 0 ) {         return  i;     }          if  (o1.getName() == null ) {         return  1 ;     } else  if  (o2.getName() == null ) {         return  -1 ;     }     return  o1.getName().compareTo(o2.getName()); }; 
 
Stream.sorted() 
 
List<Integer> list = new  ArrayList <>(Arrays.asList(1 , 3 , 2 , 6 , 5 , 4 , 9 , 7 )); list.stream().sorted().forEachOrdered(System.out::print); list.stream().sorted((o1, o2) -> o1 - o2).forEachOrdered(System.out::print); list.stream().sorted(Comparator.comparingInt(o -> o)).forEachOrdered(System.out::print); 
 
Summary: if you don’t need to keep collections always be ordered, you just use Collections sort() to get sorted collections.
Compare object list using Collections.sort(objectList)
public class Animal implements Comparable<Animal> {     private String name;          @Override     public int compareTo(Animal o) {         return this.name.compareTo(o.name);     } }  
 
List<Animal> list = new  ArrayList <>(); Collections.sort(list); Collections.sort(list, Collections.reverseOrder()); 
 
Reversion 
Using void Collections.reverse(list) 
 
List  list  =  Arrays.asList("a" , "b" , "c" );Collections.reverse(list); System.out.println(list); 
 
Using for loop 
 
List<String> list = Arrays.asList("a" , "b" , "c" ); for  (int  i  =  0 ; i < list.size() / 2 ; i++) {    String  temp  =  list.get(i);     list.set(i, list.get(list.size() - i - 1 ));     list.set(list.size() - i - 1 , temp); } System.out.println(list); 
 
Using recursion 
 
private  static  void  reverse (List<String> list)  {    if  (list == null  || list.size() <= 1 ) {         return ;     }     String  value  =  list.remove(0 );     reverse(list);     list.add(value); } public  static  void  main (String[] args)  {    List<String> list = new  ArrayList <>(Arrays.asList("a" , "b" , "c" , "d" ));     reverse(list);     System.out.println(list); } 
 
Items in a stream map to lists and collect all lists to one list Using Stream.flatMap()
List<Integer> list = Arrays.asList(1 , 2 , 3 ); Map<Integer, List<String>> map = new  HashMap <>(); map.put(1 , Arrays.asList("a" , "b" )); map.put(2 , Arrays.asList("c" , "d" )); List<String> resultList = list.stream().flatMap(item ->         Optional.ofNullable(map.get(item))             .map(List::stream)             .orElse(Stream.empty()))     .collect(Collectors.toList()); System.out.println(resultList);  
 
Computation Reduction for loop
List<Integer> numbers = Arrays.asList(1 , 2 , 3 , 4 , 5 ); int  sum  =  0 ;for  (int  x : numbers) {    sum += x; } 
 
stream
List<Integer> numbers = Arrays.asList(1 , 2 , 3 , 4 , 5 ); int  sum  =  numbers.stream().reduce(0 , (x, y) -> x + y);
 
List<Integer> numbers = Arrays.asList(1 , 2 , 3 , 4 , 5 ); int  sum  =  numbers.stream().reduce(0 , Integer::sum);
 
List<Integer> numbers = Arrays.asList(1 , 2 , 3 , 4 , 5 ); Integer  sum  =  numbers.stream().collect(Collectors.summingInt(Integer::intValue));
 
parallel stream (operations can run safely in parallel with almost no modification)
int  sum  =  numbers.parallelStream().reduce(0 , Integer::sum);
 
Group and aggregation Group
groupingBy() 
partitioningBy() 
 
Map<Department, List<Employee>> byDept = employees.stream()     .collect(Collectors.groupingBy(Employee::getDepartment)); Map<Integer, Set<Integer>> userToRoleIds = userRoles.stream().collect(Collectors.groupingBy(UserRole::getUserId, Collectors.mapping(AssignmentDept::getRoleId, Collectors.toSet()))); Map<Boolean, List<Student>> passingFailing = students.stream()     .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD)); 
 
Aggregation
max(), maxBy() 
min(), minBy() 
average(), averagingInt() 
sum(), summingInt() 
counting() 
 
Max
List<Integer> numbers = Arrays.asList(1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ); 
 
max()
int  max  =  numbers		.stream() 		.mapToInt(Integer::intValue) 		.max() 		.orElse(0 ); 
 
maxBy()
int  max  =  numbers.stream().		collect(Collectors.maxBy(Comparator.naturalOrder())) 		.orElse(0 ); System.out.println(max); 
 
Average
List<Integer> numbers = Arrays.asList(1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ); 
 
average()
double  average  =  numbers		.stream() 		.mapToInt(Integer::intValue) 		.average() 		.orElse(0.0 ); System.out.println(average); 
 
averagingInt()
double  average  =  numbers.stream().collect(Collectors.averagingInt(a -> a));System.out.println(average); 
 
Sum
List<Integer> numbers = Arrays.asList(1 , 2 , 3 , 4 , 5 ); 
 
sum()
int  sum  =  numbers		.stream() 		.mapToInt(a -> a) 		.sum(); System.out.println(sum); 
 
summingInt()
int  sum  =  numbers.stream().collect(Collectors.summingInt(Integer::intValue));
 
summarizingInt()
long  sum  =  Stream.of(1 , 2 , 3 )          .collect(Collectors.summarizingInt(Integer::intValue))           .getSum(); 
 
Sum of each group
Map<Department, Integer> totalByDept = employees.stream()     .collect(Collectors.groupingBy(Employee::getDepartment,                                    Collectors.summingInt(Employee::getSalary))); 
 
Sort by grouped fields
Map<String, Double> averageAgeByType = userList     .stream()     .collect(Collectors.groupingBy(User::getType,                                    TreeMap::new ,                                    Collectors.averagingInt(User::getAge))); 
 
Map<String, Double> userAverageAgeMap2 = userList     .stream()     .sorted(Comparator.comparing(User::getType))     .collect(Collectors.groupingBy(User::getType,                                    LinkedHashMap::new ,                                    Collectors.averagingInt(User::getAge))); 
 
Java Code Example articles 
References