11.1.2.1 使用可变数据结构

728 篇文章 1 订阅
349 篇文章 0 订阅

11.1.2.1 使用可变数据结构

 

在清单11.4 中,可以看到两个函数,处理的集合保存了前面示例的地名。这一次,我们使用C#,把地名保存在标准的List<T> 类型中,它是可变的。

 

清单11.4 处理保存在List<T> 中的地名(C#)

List<string> LoadPlaces() {     [1]

  returnnew List<string> { "Seattle", "Prague",

    "NewYork", "Grantchester", "Cambridge" };

}

void PrintLongest(List<string> names){   [2]

  varlongest = names[0];   <-- 第一外地名

  for(inti = 1; i < names.Count; i++)

    if(names[i].Length > longest.Length) longest = names[i];   <-- 记住当前最长的名字

  Console.WriteLine(longest);

}

void PrintMultiWord(List<string> names){   [3]

  names.RemoveAll(s=> !s.Contains(" "));   <-- 删除只有一个字的名字

  Console.WriteLine("Withspace: {0}", names.Count);

}

 

第一个函数加载样本数据[1],像前面的loadPlaces 函数一样,除了没有人口值;接下来,实现了两个处理函数,第一个函数[2]查找名字最长的地方,第二个函数[3]通过删除不包含空格的名字,确定包含多个单词地名的数量。尽管方法使用了lambda 函数的语法,但是,肯定不是函数式的:因为RemoveAll 方法修改了names 集合。如果我们要在后面的程序中使用这些函数,可以这样写代码:

 

PrintMultiWord(LoadPlaces());   // Prints'1'

PrintLongest(LoadPlaces());     // Prints 'Grantchester'

 

虽然得到了正确的结果,但是,两次调用LoadPlaces 函数,这似乎是不必要的。如果函数从数据库中加载数据,出于性能的原因,只一次检索数据会更好。可以进行简单的重构,只一次调用函数,把地名保存在局部变量中:

 

var places = LoadPlaces();

PrintMultiWord(places);  // Prints '1'

PrintLongest(places);    // Prints 'New York'

 

简单的改变之后,我们没能得到正确的结果!如果仔细阅追踪源代码,可能已经发现问题了:List<T> 是可变数据结构,函数PrintMultiWord 在调用RemoveAll 时,意外地修改了它;当我们在代码的后面调用PrintLongest 时,集合places 中只包含了一项,即“NewYork”。现在,我们看看如果使用不可变数据结构,为什么就不会出现类似的错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值