精华内容
下载资源
问答
  • 关于for循环删除集合元素几个

    千次阅读 2018-12-03 16:26:34
    1.原始的for循环删除集合元素的时候可能会漏掉某个元素 测试代码: /** * 假设需要删除集合中的所有的"A"元素 * 如果使用原始的for循环,那么就可能会漏删 */ List<String&...

    1.原始的for循环删除集合元素的时候有可能会漏掉某个元素

    测试代码:

    /**
    * 假设需要删除集合中的所有的"A"元素
    * 如果使用原始的for循环,那么就可能会漏删
    */
    List<String> list = new ArrayList<>();
    		
    		list.add("A");
    		list.add("A");
    		list.add("B");
    		for(int i=0; i<list.size(); i++) {
    			if("A".equals(list.get(i))) {
    				list.remove(i);
    			}
    		}
    		System.out.println(list);
    

    输出结果:
    [A, B]
    可以看到集合中只有一个"A"被删了,第二个"A"却还在。
    在这里插入图片描述

    其实解决办法也很简单,在删除元素之后再加一行代码i--就解决了

    2.增强型for循环删除集合元素会报出ConcurrentModificationException异常

    修改一下上面的测试代码

    List<String> list = new ArrayList<>();
    		
    		list.add("A");
    		list.add("A");
    		list.add("B");
    		for(String item : list) {
    			if("A".equals(item)) {
    				list.remove(item);
    			}
    		}
    		System.out.println(list);
    

    打印结果是ConcurrentModificationException异常。
    增强型for循环其实是编译器认可的语法,在到了虚拟机那边只认迭代器循环,所以在编译为.class文件的时候,最终还是变成了迭代器循环。通过反编译得到如下代码:

    List<String> list = new ArrayList();
            list.add("A");
            list.add("A");
            list.add("B");
            Iterator var3 = list.iterator();
    
            while(var3.hasNext()) {
                String item = (String)var3.next();
                if ("A".equals(item)) {
                    list.remove(item);
                }
            }
    

    迭代器这块比较复杂,我们从源码上慢慢探索。
    list.iterator()其实际上是获得了一个内部类Itr对象,这个类实现了Iterator接口。循环所用到的hasnext(),next()方法都是在这个类中实现的。
    以下代码来自openJDK1.8的AbstractList类中
    在这里插入图片描述
    以下代码来自ArrayList
    在这里插入图片描述

    大概理一下抛出异常的思路:
    迭代器循环每次调用next方法,next方法中第一步会先调用checkForComodification方法,checkForComodification方法中会校验modCountexpectedModCount两个变量是否一样(我把这两个变量理解为版本号),如果不一样就会抛出ConcurrentModificationException异常。
    modCount是集合的成员变量,初始值为1,当创建迭代器对象的时候,modCount会赋值给expectedModCount。当调用了list本身的remove方法的时候,会让expectedModCount自增,却不改变modCount。于是到了下一次迭代器的next方法去取集合元素的时候会先执行checkForComodification()方法判断版本号是否一致,这时候集合的版本号和迭代器的版本号不一致就抛出了异常。
    而如果是调用迭代器的remove方法,它会先调用集合的remove方法,然后执行cursor- -,再把modCount赋值给expectedModCount。这样一来既保证了下一次迭代的时候不会漏过任何元素,也避免了next方法校对版本号的时候抛出异常

    3.在循环中删除集合元素的正确方法

    在循环中删除元素的正确方法是用迭代器的remove方法

    List<String> list = new ArrayList<>();
            list.add("A");
            list.add("A");
            list.add("B");
            for(Iterator<String> i = list.iterator(); i.hasNext(); ) {
                String item = i.next();
                if ("A".equals(item)) {
                	//这里调用迭代器的rermove方法而不是集合的remove方法
                    i.remove();
                }
            }
            System.out.println(list);
    

    也许你会觉得上面的写法太麻烦,“我只是想删除集合中的所有A元素,有没有更优雅的写法呢”。答案是有的,在Java8以后,我们就可以用一行代码来完美代替上面的写法了:

    list.removeIf(item -> "A".equals(item));
    

    实际上removeIf方法内部也是用了迭代器循环
    在这里插入图片描述

    4.为什么要设计“快速报错”机制

    这是一种集合的保护机制,为了防止多个线程同时修改同一个集合的内容。我们先假设没有快速失败机制,当一条线程正在迭代遍历某个集合的过程中,另一个线程介入其中,并且删除了集合内的某个对象,那么就出问题了:就像上面说过的一样,元素被删除后,集合缩容,第一个线程要进行下一次迭代时,就会漏掉一个元素。这种数据不同步所带来的问题可能再当前步骤下不会出现异常,直到在后续的某个代码环节中才会暴露出问题,从而给我们排查定位异常带来难度。
    在这里插入图片描述
    而有了快速失败机制后,一个线程的删除了集合中的某个元素,集合的modCount+1,另一个集合调用迭代器的next方法,发现版本号不一致,于是就直接抛出异常,终止迭代,让我们能够快速的定位到问题所发生的时间和位置。

    ConcurrentHashMapCopyOnWriteArrayListCopyOnWriteArraySet都使用了可以避免ConcurrentModificationException的机制。这个话题我们下次再研究吧。

    展开全文
  • 本文来自:http://www.cnblogs.com/TrueElement/archive/2012/01/13/2321328.html ...如上,我想把num0中不包含于num1的元素都找出来,其正确结果应该是28,32。早上看到原来linq

    本文来自:http://www.cnblogs.com/TrueElement/archive/2012/01/13/2321328.html


    int[] num0 = { 28, 32, 14 };
    int[] num1 = {14,15,16};

    如上,我想把num0中不包含于num1的元素都找出来,其正确结果应该是28,32。早上看到原来linq可以写多个from字句,之后就想到了这样的写法:

    复制代码
    int[] num0 = { 28, 32, 14 };
    int[] num1 = {14,15,16};

    var qq = from n1 in num0
    from n2 in num1
    where n1 != n2
    select n1;
    复制代码

    结果,我错了,调试了一下才知道自己想当然了。结果如下:

    总共进行了3 * 3,9次比较,那个语句把所有成立的n1都选进去了。

    所以还是老老实实用contains好了

    int[] num0 = { 28, 32, 14 };
    int[] num1 = { 14, 15, 16 };

    var bb = from n1 in num0
    where num1.Contains(n1) == false
    select n1;

    另外,推荐一个工具:LinqPad,我的这个例子就是用linqPad 调试的,上面那个结果显示使用了语句:qq.Dump();

    网址:http://www.linqpad.net/

    下载:

          for .net 3.5:http://www.linqpad.net/GetFile.aspx?LINQPad.exe

          for .net 4.0:http://www.linqpad.net/GetFile.aspx?LINQPad4.zip
    这个工具还不错,自带了许多例子,还可以写入自己的语句运行。

    另外,微软官方的Official Visual Studio 2008 C# Samples里面的LINQ - Sample Queries也是不错的,带了许多例子,几乎所有的linq特性都有,还可以执行。

    网址:http://code.msdn.microsoft.com/csharpsamples

    LINQ - Sample Queries 截图:

     

    2012年1月13日16:56:23 更新:

    后来又找到了Except、Intersect、Union、Distinct等方法,终于可以排除一个集合中那些某个属性的值存在于另一个几个中元素属性的方法了。

    按照Example上的例子,大概可以如此实现:

    复制代码
    public void Linq53() {
    List<Product> products = GetProductList();
    List<Customer> customers = GetCustomerList();

    var productFirstChars =
    from prod in products
    select prod.ProductName[0];
    var customerFirstChars =
    from cust in customers
    select cust.CompanyName[0];

    var productOnlyFirstChars = productFirstChars.Except(customerFirstChars);

    Console.WriteLine("First letters from Product names, but not from Customer names:");
    foreach (var ch in productOnlyFirstChars) {
    Console.WriteLine(ch);
    }
    }
    复制代码

    展开全文
  • 初学python,因为需要,就用 python 简单实现了下,各种语言都一样,需要递归。 # A Recursion function 递归函数 def RecursionFunc(arr1,arrList): if (arrList): string = [] for x in arr1: ...

    初学python,因为需要,就用 python 简单实现了下,各种语言都一样,需要递归。

    # A Recursion function 递归函数
    
    def RecursionFunc(arr1,arrList):
        if (arrList):
            string = []
            for x in arr1:
                for y in arrList[0]:
                    string.append(x + y)
            result = RecursionFunc(string,arrList[1:])
            return result
        else:
            return arr1
    
    
    line_List = [['aa','bb','cc'],['dd','ee','ff'],['gg','hh']]
    
    caseslist = RecursionFunc(line_List[0], line_List[1:])
    
    #每条case
    for ele in caseslist:
        print(ele)
        print('***************************************\n')


    展开全文
  • 找出两List集合重复的元素

    万次阅读 热门讨论 2019-02-13 20:26:56
    天,个同事问我说怎么找出两个List集合中重复的元素,我当时就说一个集合在外面循环,一个集合在内循环,如果两个元素相等了,就找出来了,我回来一想还是不对,要是数据非常多,这样循环下去,服务器会卡死的...

    前几天,有个同事问我说怎么找出两个List集合中重复的元素,我当时就说一个集合在外面循环,一个集合在内循环,如果两个元素相等了,就找出来了,我回来一想还是不对,要是数据非常多,这样循环下去,服务器会卡死的,最后我想了想,用以下两种方法:

       List<String> list1 = new ArrayList<>();
                List<String> list2 = new ArrayList<>();
                list1.add("a");
                list1.add("b");
                list1.add("c");
                list1.add("d");
                list2.add("d");
                list2.add("f");
                list2.add("g");
                list2.add("h");
                list2.add("k");
    

    第一种方法:这是把list1集合放到list2中

     list2.addAll(list1);
            HashMap<String,Integer> mapList=new HashMap<>();
            for(String str:list2){
                int count=0;
                if(mapList.get(str)!=null){
                    count=mapList.get(str)+1;
                }
                mapList.put(str,count);
            }
            System.out.println("重复的元素是:");
            for(String key:mapList.keySet()){
                if(mapList.get(key)!=null && mapList.get(key)>0){
                    System.out.println(key);
                }
            }
    

    第二种方法:

       Map<String,String> map=new HashMap<>();
            String str=null;
            String stp=null;
            String psp=null;
            for(int i=0;i<list1.size();i++){
                str=list1.get(i);
                map.put(str,str);
            }
            for(String spt:map.keySet()){
                System.out.println("key:"+spt+"-----------value:"+map.get(spt));
            }
            System.out.println("==========="+map.entrySet());
            for(int i=0;i<list2.size();i++){
                stp=list2.get(i);
                if(stp.equals(map.get(str))){
                    System.out.println("重复的元素:"+stp);
                }
            }
    

    以上就是我用的两种方法,由于是个菜鸟,所以大神们有更好的方法望指点,在下感激不尽!


    补充:
    下面是java8新特性去list集合重复的方法,非常简单,比前的方法简单多了,
    首先是将两个集合合并在一起,然后就是下面的方法:(list2是合并以后的集合,spa是去重复的新集合)

     List<String> spa = list2.stream()
                        .distinct()
                        .collect(Collectors.toList());
    

    这种方法最简单,代码少,清晰明了!!!!


    补充:
    java8的方法中可以找出相同的元素 代码如下:

    	public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            list.add("a");
            list.add("b");
            list.add("c");
            list.add("d");
            list.add("a");
            list.add("b");
            System.out.println(getDuplicateElements(list.stream()));
        }
    
        public static <T> List<T> getDuplicateElements(Stream<T> stream) {
            return stream.collect(Collectors.groupingBy(p -> p,Collectors.counting()))
                    .entrySet().stream() // Set<Entry>转换为Stream<Entry>
                    .filter(entry -> entry.getValue() > 1) // 过滤出元素出现次数大于 1 的 entry
                    .map(entry -> entry.getKey()) // 获得 entry 的键(重复元素)对应的 Stream
                    .collect(Collectors.toList()); // 转化为 List
        }
    

    执行结果如下:

    [a, b]
    

    由于在方法中使用了泛型,所以可以接收任意类型的流,注意在如果是对象,别忘了重写其 hashCode() 和 equals() 方法。

    展开全文
  • 要求:现在想把集合中的某个元素,放到该集合的第一个位置,但是其他元素的顺序不需要管。 方法:需要遍历集合,找到这个元素集合中的位置,然后使用Collections.swap(list,o,i) (O:为元素目前所在位置,i:为...
  • 题目遇到这么一个面试题,题目是...然后将S0中的元素一个一个的放入S1中,在这个过程中做如下操作: 1. 将第一个元素i1放入集合S1中,即S1{i1},在S1中随机取一个元素的话只能取i1; 2. 再将元素i2放入集合S1中,即S1
  • 问题描述 在.NET/C#应用程序编程开发中,如何判断一个字符串集合List<string>中是否重复的元素? ...现在有一个简单的判断/检查lstNames字符串集合中是否重复元素的实现,如下: i...
  • 1、改变list中某个元素的值 public class tb_SensorRecordModel { public int ID { get; set; } public decimal Value1 { get; set; } } List<tb_SensorRecordModel> list = new...
  • 【m元素集合的n个元素子集】

    千次阅读 2018-05-03 12:33:28
    假设集合拥有m个元素,任意的从集合中取出n个元素,则这n个元素所形成的可能子集那些? 解法: 假设5个元素的集点,取出3个元素的可能子集如下: {1 2 3} 、{1 2 4 } 、{1 2 5} 、{1 3 4} 、{1 3 5} ...
  • package container; import java.util.*; /** * 给集合添加一组元素的集中方法 */ public class AddingGroups { public static void main(String... //直接通过构造方法,添加一个集合 Collection collection = ne
  • 多个集合个元素的排序组合

    千次阅读 2018-04-21 19:40:57
    从各个集合当中任意取一个元素,生成集合的排列组合。import java.util.ArrayList; import java.util.List; public class Permutate { /**保存生成的排列组合内容**/ public List&lt;String&gt; ...
  • 在C#的List集合操作过程中,如果要获取List集合中的最后一个元素对象,则一般会先通过获取到list集合的个数Count属性,然后再使用索引的方式获取到该集合的最后一个位置的元素信息。其实在List集合中提供了获取最后...
  • 思路:维护一个数组,代表以某个结点为根的树的结点数目,初始化为全1。在合并两个集合时,将秩较小的集合元素数目加到秩较大的集合上。这里需要注意一下,就是Union过程处理两个祖先相同的结点,此时实际上没有...
  • 删除集合中特定元素种情况

    千次阅读 2019-01-23 15:44:35
    集合中删除元素一直是一个比较容易遗漏的知识点,今天来给大家介绍一下删除集合​​中特定元素的一些情况。 ​(一)List如何实现遍历删除 以ArrayList为例  List&lt;String&gt; a1 = new ArrayList...
  • 在两数据量很大的list集合中(每个集合都是10万条数据,集合元素为Student对象),怎么查找 # 两个集合中Student对象name属性相同的元素
  • 做了好几个题目都遇到题中的场景。于是写了个算法,元素组合条件是求和。 算法能适应的场景要求组合条件可以拆分的,对应的逆运算。代码实现的是取三个元素和在40~60之间的组合。循环n(testList.size())次可以...
  • List集合一次删除多个元素

    千次阅读 2018-12-18 10:58:26
    JAVA中循环遍历list三种方式: for循环、增强for循环(也就是常说的foreach循环)、iterator遍历。 1、for循环遍历list for(int i=0;i&lt;list.size();i++){ if(list.get(i).equals("abc")) ...
  • 在C#的List集合操作过程中,如果要获取List集合中的第一个元素对象,则一般会先通过...例如个List集合的对象list1,需要获取到该集合对象的第一个元素可使用First()方法,具体如下: List list1 = new List()...
  • 本代码有一处需要优化的地方 大佬能帮忙优化就万分感谢了 暂时 此段代码 检索小集合没有问题 Integer[] inv2 = inv.clone(); reslist.add(inv2); 此处代码 可能会导致 内存溢出 在此 如果代码上又和其他人冲突的...
  • List集合元素几种排序方法总结

    千次阅读 2018-03-07 11:34:49
    排序方法(直接排序) List&lt;String&gt; names=new ArrayList&lt;String&gt;(); List&lt;Integer&gt; ages=new ArrayList&lt;Integer&gt;(); Collections.sort(names); ...
  • c:forEach 遍历集合中的元素,判断是否是最后一个元素       ${chl.section}          ${chl.section}       中 varS
  • List 集合去除 null 元素

    千次阅读 2018-06-27 18:33:28
    在 JavaWeb 开发过程中,我们时候会遇到 jsp 以集合的形式向后台传输数据,这时候如果集合有几个 null 元素,我们后台就必须对数据进行非空处理,总结了 2 种处理这种情况的方法,方便参考。)使用 for 循环...
  • java Collection集合删除某一元素方法汇总

    千次阅读 多人点赞 2016-09-13 11:22:32
    无论在自己写程序玩还是实际项目应用中,操作java.util.Collection结合都是最常用的,而且也是最重要的...下面总结了从集合中删除某一元素种方法 package test; import java.text.MessageFormat; import java.util
  • 前面篇我们学习HashSet和LinkedHashSet的原理和基本使用,这篇,我们来练习下这两类的相关的集合编程练习题。.生成101到20之间的不重复的随机数分析过程:1. 需要生成随机数,那么需要Random类2. 需要存储10...
  • php获取数组第一个元素种方法

    万次阅读 2018-05-24 18:22:18
    1:array_shift();//弹出数组第一个元素举例$a...$new是第一个元素值,取最后一个元素可以用array_pop(),这种操作会改变原数组的内容2:array_slice();//截取数组举例:$a=array('new','hello','cool');$new=array_slice...
  • 在写程序的场景中有时会遇到这样的比较,假设一个集合A含有{数学,语文,英语}三个元素集合B含有{语文,英语,数学}一样的三个元素,我们相比较A和B是否相同。单从我们直观的观察来看,这两个集合必定是相同的。...
  • Java判断一个数组是否相同的元素

    千次阅读 2019-10-27 22:11:11
    1.如果只是需要判断是否包含相同元素而不需要找出相同元素是哪些,直接放在set集合中,然后看set集合和数组长度是否一致即可 import java.util.HashSet; import java.util.Set; public class Test { public ...
  • Collections.nCopies(int n, T o) 创建一个包含n个重复元素o的集合 可以随意使用这个 set(int index, E element) 随意设置index是n的value,而不会出现 IndexOutOfBoundsException 异常 当然在数组范围内 这个...
  • 为什么标题上说是删除多个元素,难倒删除多个元素和删除单个元素什么区别?常见的for循环遍历中删除元素具体代码如下/** * @ClassName: ForDemo * @Description: TODO(通过for循环来测试,删除集

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 396,317
精华内容 158,526
关键字:

一个集合有几个元素