String转化为List,进行去重、比较操作
目录
一、String To List
1、首先想到使用的方法是:Arrays.asList();
/**
* Returns a fixed-size list backed by the specified array. (Changes to
* the returned list "write through" to the array.) This method acts
* as bridge between array-based and collection-based APIs, in
* combination with {@link Collection#toArray}. The returned list is
* serializable and implements {@link RandomAccess}.
*
* <p>This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
* <pre>
* List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
* </pre>
*
* @param <T> the class of the objects in the array
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
2、从源码介绍中可以了解到,asList()方法参数需要是一个数组才行,如果你是一个字符串它也能实现转化,但是转化出来的List只有一个元素就是这个字符串本身,并不能达到string to list的效果
依赖数组,后边也会用到
private String s1 = "4,71,32,789,65";
private String s2[] = {"4","71","32","789","65"};
private String s3 = "4,71,32,789,65";
private String s4 = "789,32,4,71,65";
List<String> list1 = Arrays.asList(s1);
System.out.println("s1 = " + s1);
System.out.println("Arrays.aiList(s1) 转化后size长度为:" + list1.size() + " ,值为:" + list1.toString());
List<String> list2 = Arrays.asList(s2);
System.out.println("Arrays.aiList(s2) 转化后size长度为:" + list2.size() + " ,值为:" + list2.toString());
结果:
s1 = 4,71,32,789,65
Arrays.aiList(s1) 转化后size长度为:1 ,值为:[4,71,32,789,65]
Arrays.aiList(s2) 转化后size长度为:5 ,值为:[4, 71, 32, 789, 65]
3、我们可以使用slip()方法,先将字符串划分为数组,然后再用asList()方法将数组转化为list
List<String> list3 = Arrays.asList(s1.split(","));
System.out.println("Arrays.aiList(s1.split(\",\")) 转化后size长度为:" + list3.size() + " ,值为:" + list3.toString());
Arrays.aiList(s1.split(",")) 转化后size长度为:5 ,值为:[4, 71, 32, 789, 65]
4、进行List操作,会报错:java.lang.UnsupportedOperationException
System.out.println(list3.getClass());
list3.add("1");//报错:java.lang.UnsupportedOperationException
class java.util.Arrays$ArrayList
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at csdn.ListTest.strings2List(ListTest.java:26)
at csdn.ListTest.main(ListTest.java:109)
用getClass()方法可以查出list3属于class java.util.Arrays$ArrayList
asList()方法返回的是Arrays数组里面的一个内部类ArrayList,但并非我们想要的java.util.ArrayList,它实际并没有集合的属性,不能用集合的方式对其进行修改,我们可以使用new ArrayList()创建一个新的java.util.ArrayList对象,将其放入。
List<String> list4 = new ArrayList<>(list3);
list4.add("1");
System.out.println(list4.toString());
[4, 71, 32, 789, 65, 1]
5、总结String To List只需一行代码
List<String> list = new ArrayList<>(Arrays.asList(s1.split(",")));
二、去除一个list中与另一个list的重复值
依赖list
private String s1 = "4,71,32,789,65";
private String s2[] = {"4","71","32","789","65"};
private String s3 = "4,71,32,789,65";
private String s4 = "789,32,4,71,65";
private List<String> list1 = new ArrayList<>(Arrays.asList(s1.split(",")));
private List<String> list2 = new ArrayList<>(Arrays.asList(s3.split(",")));
private List<String> list3 = new ArrayList<>(Arrays.asList(s4.split(",")));
1、来一个简单的方法试一次--for循环正序遍历(可行)
for (int i = 0; i < list1.size(); i++) {
if(list2.contains(list1.get(i))){
list1.remove(i);
}
}
System.out.println(list1);
[71, 789]
显然是错误的,应该返回空值才对,因为每一有相同值的时候,list1会remove掉一个元素,对应后边的值会往前补,下一次你再去取数据的时候,会错过一个数据。具体可以打个断点,跟下代码,就能看出其中的奥妙。既然这样,我们可以在每一次remove元素是对i进行减1操作,来确保吧list1的值全部遍历完
for (int i = 0; i < list1.size(); i++) {
if(list2.contains(list1.get(i))){
list1.remove(i);
i--;
}
}
2、for循环倒序遍历,倒序遍历不必担心,remove掉一个元素后还有后边的元素往前补位,因为后边的元素都处理过了,再怎么补也不影响最终结果。(成功)
/**
* for循环倒序遍历
*/
private void removeRepeat2(){
//for循环倒序遍历 遍历完全,去重成功
for (int i = list1.size()-1; i >= 0; i--) {
if(list2.contains(list1.get(i))){
list1.remove(i);
}
}
System.out.println(list1);
}
3、用forEach()试一下(报错)
list1.forEach(s -> {
if (list2.contains(s)){
list1.remove(s);
}
});
运行报错:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList.forEach(ArrayList.java:1262)
at csdn.ListTest.removeRepeat3(ListTest.java:75)
at csdn.ListTest.main(ListTest.java:112)
提示的事75行,对应代码中是remove的时候出错了:java.util.ConcurrentModificationException
引用参考博客的内容:https://blog.csdn.net/qq_35462323/article/details/99318628
首先java的foreach循环其实就是根据list对象创建一个Iterator迭代对象,用这个迭代对象来遍历list,相当于list对象中元素的遍历托管给了Iterator,你如果要对list进行增删操作,都必须经过Iterator。iterator创建的时候modCount被赋值给了expectedModCount,但是调用list的add和remove方法的时候不会同时自动增减expectedModCount,这样就导致两个count不相等,从而抛出异常。
4、用Iterator迭代器试一下(成功)
Iterator iterator = list1.listIterator();
while (iterator.hasNext()){
if (list2.contains(iterator.next())){
iterator.remove();
}
}
引用参考博客的内容:https://blog.csdn.net/weixin_44727906/article/details/91791982
Iterator.remove() 方法会在删除当前迭代对象的同时,会保留原来元素的索引。所以用迭代删除元素是最保险的方法,建议大家使用List过程中需要删除元素时,使用这种方式。
5、用集合removeAll()方法(成功)
List<String> list4 = new ArrayList<>(Arrays.asList("1","2","3","4"));
List<String> list5 = new ArrayList<>(Arrays.asList("2","3","1"));
// list4.retainAll(list5);//交集,重复部分
// System.out.println(list4);
list4.removeAll(list5);
System.out.println(list4);
结果:[4]
如果list内部有重复元素,在removeAll()的时候也可以直接remove掉。但如果要求交集,应该先用set去除内部重复元素再取交集。
三、比较两个List是否相同
依赖list
private String s1 = "4,71,32,789,65";
private String s2[] = {"4","71","32","789","65"};
private String s3 = "4,71,32,789,65";
private String s4 = "789,32,4,71,65";
private List<String> list1 = new ArrayList<>(Arrays.asList(s1.split(",")));
private List<String> list2 = new ArrayList<>(Arrays.asList(s3.split(",")));
private List<String> list3 = new ArrayList<>(Arrays.asList(s4.split(",")));
1、首先我们可以用去重的方法,如果去重结果得到的List我空,说明两个List相同
private void compareTwoList(){
if(list1.size() != list3.size()){
System.out.println(false);
return;
}
Iterator iterator = list1.listIterator();
while (iterator.hasNext()){
if (list2.contains(iterator.next())){
iterator.remove();
}
}
if(list1.size() == 0){
System.out.println(true);
}else {
System.out.println(false);
}
}
2、排序后逐个比较
private void compareTwoList1(){
if(list1.size() != list3.size()){
System.out.println(false);
return;
}
//先用Collections工具类sort方法进行排序,这样保证两个集合排序规则一致
Collections.sort(list1);
Collections.sort(list3);
for (int i = 0; i < list1.size(); i++) {
if(!list3.get(i).equals(list1.get(i))){
System.out.println(false);
return;
}
}
System.out.println(true);
}
四、附上所有代码
package csdn;
import java.util.*;
public class ListTest {
private String s1 = "4,71,32,789,65";
private String s2[] = {"4","71","32","789","65"};
private String s3 = "4,71,32,789,65";
private String s4 = "789,32,4,71,65";
private List<String> list1 = new ArrayList<>(Arrays.asList(s1.split(",")));
private List<String> list2 = new ArrayList<>(Arrays.asList(s3.split(",")));
private List<String> list3 = new ArrayList<>(Arrays.asList(s4.split(",")));
private void strings2List(){
//用Arrays.aiList()方法进行转化
List<String> list1 = Arrays.asList(s1);
System.out.println("s1 = " + s1);
System.out.println("Arrays.aiList(s1) 转化后size长度为:" + list1.size() + " ,值为:" + list1.toString());
List<String> list2 = Arrays.asList(s2);
System.out.println("Arrays.aiList(s2) 转化后size长度为:" + list2.size() + " ,值为:" + list2.toString());
List<String> list3 = Arrays.asList(s1.split(","));
System.out.println("Arrays.aiList(s2.split(\",\")) 转化后size长度为:" + list3.size() + " ,值为:" + list3.toString());
System.out.println(list3.getClass());
// list3.add("1");//报错:java.lang.UnsupportedOperationException
List<String> list4 = new ArrayList<>(list3);
list4.add("1");
System.out.println(list4.toString());
List<String> list = new ArrayList<>(Arrays.asList(s1.split(",")));
}
/**
* for循环正序遍历
*/
private void removeRepeat1(){
//for循环正序遍历 遍历不全,去重失败
// for (int i = 0; i < list1.size(); i++) {
// if(list2.contains(list1.get(i))){
// list1.remove(i);
// }
// }
// System.out.println(list1);
//for循环正序遍历改进 遍历完全,去重成功
for (int i = 0; i < list1.size(); i++) {
if(list2.contains(list1.get(i))){
list1.remove(i);
i--;
}
}
System.out.println(list1);
}
/**
* for循环倒序遍历
*/
private void removeRepeat2(){
//for循环倒序遍历 遍历完全,去重成功
for (int i = list1.size()-1; i >= 0; i--) {
if(list2.contains(list1.get(i))){
list1.remove(i);
}
}
System.out.println(list1);
}
/**
* forEach循环
* Iterator迭代器
*/
private void removeRepeat3(){
//forEach循环不可用 报错:java.util.ConcurrentModificationException
// list1.forEach(s -> {
// if (list2.contains(s)){
// list1.remove(s);
// }
// });
//Iterator迭代器
Iterator iterator = list1.listIterator();
while (iterator.hasNext()){
if (list2.contains(iterator.next())){
iterator.remove();
}
}
System.out.println(list1);
}
private void removeRepeat4(){
List<String> list4 = new ArrayList<>(Arrays.asList("1","2","3","4"));
List<String> list5 = new ArrayList<>(Arrays.asList("2","3","1"));
// list4.retainAll(list5);//交集,重复部分
// System.out.println(list4);
list4.removeAll(list5);
System.out.println(list4);
}
private void compareTwoList(){
if(list1.size() != list3.size()){
System.out.println(false);
return;
}
Iterator iterator = list1.listIterator();
while (iterator.hasNext()){
if (list2.contains(iterator.next())){
iterator.remove();
}
}
if(list1.size() == 0){
System.out.println(true);
}else {
System.out.println(false);
}
}
private void compareTwoList1(){
if(list1.size() != list3.size()){
System.out.println(false);
return;
}
//先用Collections工具类sort方法进行排序,这样保证两个集合排序规则一致
Collections.sort(list1);
Collections.sort(list3);
for (int i = 0; i < list1.size(); i++) {
if(!list3.get(i).equals(list1.get(i))){
System.out.println(false);
return;
}
}
System.out.println(true);
}
public static void main(String[] args) {
ListTest listTest = new ListTest();
// listTest.strings2List();
// listTest.removeRepeat1();
// listTest.removeRepeat2();
// listTest.removeRepeat3();
// listTest.removeRepeat4();
// listTest.compareTwoList();
// listTest.compareTwoList1();
}
}