一、想对你说
(1)之前一直有小伙伴让我总结下Java相关的知识点,这里我针对有一定Java基础的同学做了一个系列的总结,感兴趣的同学可以看看顶部的【Java专栏】希望对大家有所帮助。
(2)要是对您有所帮助的话,可以给 “大大大钢琴” 点个赞,这是我继续下去的动力,谢谢大家了!废话不多说了,直接上干货。
二、List类排序方式
(一)List类介绍
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下 >标)来访问List中的元素,这类似于Java的数组。
总结
(1)所有的List中只能容纳单个不同类型的对象组成的表,而不是Key-Value键值对。例如:[ tom,1,c ]
(2)所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ]
(3)所有的List中可以有null元素,例如[ tom,null,1 ]
(4)基于Array的List(Vector,ArrayList)适合查询,而LinkedList 适合添加,删除操作
以下是list方法的使用、以及调用的方法定义
import java.util.*;
public class test_demo {
public static void main(String[] args) throws Exception {
System.out.println("开始:");
String a = "A", b = "B", c = "C", d = "D", repeat = "Repeat";
List<String> list = new ArrayList<String>();
list.add(a); // 索引位置为 0
list.add(repeat); // 索引位置为 1
list.add(b); // 索引位置为 2
list.add(repeat); // 索引位置为 3
list.add(c); // 索引位置为 4
list.add(repeat); // 索引位置为 5
list.add(d); // 索引位置为 6
System.out.println(list.indexOf(repeat));//开始第一个"Repeat"索引
System.out.println(list.lastIndexOf(repeat));//结尾第一个"Repeat"索引
System.out.println(list.indexOf(b));//开始第一个"b"索引
System.out.println(list.lastIndexOf(b));//结尾第一个"b"索引
System.out.println("结束!");
}
void testFunction(){
List list = new ArrayList();
list.add("test01");// 向列表的尾部追加指定的元素
list.add(1, "test01");// 在列表的指定位置插入指定元素
list.addAll(new ArrayList());// 追加指定 collection 中的所有元素到此列表的结尾
list.clear(); // 从列表中移除所有元素
list.contains("test");// 如果列表包含指定的元素,则返回true
list.containsAll(new ArrayList()); // 如果列表包含指定 collection 的所有元素,则返回 true
list.equals(new ArrayList());// 比较指定的对象与列表是否相等
list.get(0); // 返回列表中指定位置的元素
list.hashCode(); // 返回列表的哈希码值
list.indexOf("lwc"); // 返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1
list.lastIndexOf("lwc"); // 返回列表中最后出现指定元素的索引,如果列表不包含此元素,则返回 -1
list.isEmpty(); // 如果列表不包含元素,则返回 true
list.remove(0); // 移除列表中指定位置的元素
list.remove("lwc"); // 移除列表中出现的首个指定元素
list.removeAll(new ArrayList()); // 从列表中移除指定 collection 中包含的所有元素
list.set(0, "lp"); // 用指定元素替换列表中指定位置的元素
list.size(); // 返回列表中的元素数
list.subList(1, 2); // 返回列表中指定的fromIndex(包括)和toIndex(不包括)之间的部分视图
list.toArray(); // 返回以正确顺序包含列表中的所有元素的数组
list.toArray(new String[] { "a", "b" }); // 返回以正确顺序包含列表中所有元素的数组
}
}
(二)List 声明(6种)
Java 中初始化 List 的五种方法
(1)构造 List 后使用 List.add 初始化
(2)使用 {{}} 双括号语法
(3)使用 Arrays.asList
(4)使用 Stream (JDK8)
(5)使用 Lists (JDK9)
(6)使用guava包的Lists(推荐使用)
import org.testng.collections.Lists;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class test_demo {
public static void main(String[] args) {
//Java 中初始化 List 的五种方法
//(1)构造 List 后使用 List.add 初始化
//(2)使用 {{}} 双括号语法
//(3)使用 Arrays.asList
//(4)使用 Stream (JDK8)
//(5)使用 Lists (JDK9)
//(6)使用guava包的Lists(推荐使用)
//1、构造 List 后使用 List.add 初始化
List<String> stringList1 = new LinkedList<>();
stringList1.add("a");
stringList1.add("b");
System.out.println("方法1:" + stringList1);
//2、使用 {{}} 双括号语法
List<String> stringList2 = new LinkedList<String>(){{
add("a");
add("b");
}};
System.out.println("方法2:" + stringList2);
//3、使用 Arrays.asList
List<String> stringList3 = Arrays.asList("a", "b", "c");
System.out.println("方法3:" + stringList3);
//分步骤(先建数组,再存入list)
int[] intArray = new int[]{1, 2, 3};
Integer[] integerArray = new Integer[]{1, 2, 3};
List<int[] > intArrayList = Arrays.asList(intArray);
List<Integer> integerList = Arrays.asList(integerArray);
List<Integer> integerList2 = Arrays.asList(1, 2, 3);
//4、使用 Stream (JDK8)
List<String> stringList4 = Stream.of("a", "b","c").collect(Collectors.toList());
System.out.println("方法4:" + stringList4);
//5、使用 Lists (JDK9)
List<String> stringList5 = Lists.newArrayList("a", "b", "c");
System.out.println("方法5:" + stringList5);
//6、使用 guava包的Lists
//使用方法同上,提出这种方法主要是很多项目还是java8,没法直接用java9的List。
List<Integer> stringList6 = Lists.newArrayList(1, 2, 3);
System.out.println("方法6:" + stringList6);
}
}
(三)List 去重方式(6种)
反问问题:为什么不直接使用 Set 或者 LinkedHashSet 呢
实际场景:实际的业务开发中遇到的情况会更复杂。比如,List 集合可能是历史遗留问题,也有可能是调用接口返回的类型限制,只能使用 List 接收,又或者是代码写了一半,在做多个集合合并的时候才发现了这个问题
3.1:contains判断去重(有序)
此方法的优点的:理解起来比较简单,并且最终得到的集合也是有序的,这里的有序指的是新集合的排列顺序和原集合的顺序是一致的;但缺点是实现代码有点多,不够简洁优雅。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class test_demo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 5, 2, 1, 3, 7, 2);
System.out.println("原集合:" + list);//原集合:[1, 3, 5, 2, 1, 3, 7, 2]
// 新集合:contains方法如果新集合中不存在则插入
List<Integer> newList = new ArrayList<>(list.size());
list.forEach(i -> {
if (!newList.contains(i)) {
newList.add(i);
}
});
System.out.println("去重集合:" + newList);//去重集合:[1, 3, 5, 2, 7]
}
}
3.2:迭代器去重(无序)
此方法的实现比上一种方法的实现代码要少一些,且不需要新建集合,但此方法得到的新集合是无序的,也就是新集合的排列顺序和原集合不一致,因此也不是最优的解决方案。
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class test_demo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 5, 2, 1, 3, 7, 2);
System.out.println("原集合:" + list);//原集合:[1, 3, 5, 2, 1, 3, 7, 2]
//使用迭代器去重
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer item = iterator.next(); // 获取循环的值
if (list.indexOf(item) != list.lastIndexOf(item)) {
iterator.remove();// 如果2个值相同:移除最后那个相同的值
}
}
System.out.println("去重集合:" + list);//新集合:[5, 1, 3, 7, 2]
}
}
3.3:HashSet去重(无序)
此方法的实现代码较为简洁,但缺点是 HashSet 会自动排序,这样新集合的数据排序就和原集合不一致了,如果对集合的顺序有要求,那么此方法也不能满足当前需求。
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class test_demo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 5, 2, 1, 3, 7, 2);
System.out.println("原集合:" + list);//原集合:[1, 3, 5, 2, 1, 3, 7, 2]
//使用 HashSet 去重
HashSet<Integer> set = new HashSet<>(list);
System.out.println("去重集合:" + set);//去重集合:[1, 2, 3, 5, 7]
}
}
3.4:TreeSet去重(无序)
比较遗憾的是,TreeSet 虽然实现起来也比较简单,但它有着和 HashSet 一样的问题,会自动排序,因此也不能满足我们的需求。
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;
public class test_demo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 5, 2, 1, 3, 7, 2);
System.out.println("原集合:" + list);//原集合:[1, 3, 5, 2, 1, 3, 7, 2]
// 使用 TreeSet 去重(无序)
TreeSet<Integer> set = new TreeSet<>(list);
System.out.println("去重集合:" + set); //去重集合:[1, 2, 3, 5, 7]
}
}
3.5:LinkedHashSet去重(有序)
从代码和执行结果可以看出,LinkedHashSet 是到目前为止,实现比较简单,且最终生成的新集合与原集合顺序保持一致的实现方法,是我们可以考虑使用的一种去重方法。
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
public class test_demo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 5, 2, 1, 3, 7, 2);
System.out.println("原集合:" + list);//原集合:[1, 3, 5, 2, 1, 3, 7, 2]
// 使用 LinkedHashSet 去重
LinkedHashSet<Integer> set = new LinkedHashSet<>(list);
System.out.println("去重集合:" + set); //去重集合:[1, 3, 5, 2, 7]
}
}
3.6:Stream去重(有序)
Stream 实现去重功能和其他方法不同的是,它不用新创建集合,使用自身接收一个去重的结果就可以了,并且实现代码也很简洁,并且去重后的集合顺序也和原集合的顺序保持一致,是我们最优先考虑的去重方法。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class test_demo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 5, 2, 1, 3, 7, 2);
System.out.println("原集合:" + list);//原集合:[1, 3, 5, 2, 1, 3, 7, 2]
// 使用 Stream 去重
list = list.stream().distinct().collect(Collectors.toList());
System.out.println("去重集合:" + list); //去重集合:[1, 3, 5, 2, 7]
}
}
3.7:补充:currentTimeMillis测试方法执行时间
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class test_demo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 5, 2, 1, 3, 7, 2);
System.out.println("原集合:" + list);//原集合:[1, 3, 5, 2, 1, 3, 7, 2]
// 使用 currentTimeMillis,获取时间节点
long startTime ;
long endTime;
startTime = System.currentTimeMillis();
list = list.stream().distinct().collect(Collectors.toList());
System.out.println("去重集合:" + list);
endTime = System.currentTimeMillis();
System.out.println("使用collect实现List去重时间:"+(endTime-startTime)+"毫秒");
}
}