我有一个通用的List
,我必须在此列表中找到一个特定的字符串。能告诉我下面哪种方法最好吗?
if (strlist.Contains("Test"))
{
// String found
}
或
string res = (from d in strlist where d == "Test" select d).SingleOrDefault();
if (res == "Test")
{
//found
}
请考虑从数据库填充的列表可能非常大。您对此的看法非常感谢。
答案 0 :(得分:5)
如果您有List<string>
(或甚至IEnumerable<string>
)并且包含符合您的需求,请使用包含。
如果你需要一些Contains没有提供的额外处理,我建议使用Any():
if(strList.Any(s => s.StartsWith("Tes"))
{
// Found
}
答案 1 :(得分:2)
如果有多个匹配,这两种方法的行为会有所不同;第一个将返回true,第二个将抛出异常。
要更正此问题,请将SingleOrDefault
更改为FirstOrDefault
。
要回答这个问题,如果您正在搜索完全匹配,则应致电Contains
,如果不是,则应致电Any
。
例如:
if (strings.Contains("SomeString", StringComparer.OrdinalIgnoreCase))
if (strings.Any(s => s.StartsWith("b"))
答案 2 :(得分:0)
你真的应该使用HashSet<string>
,因为Contains
的表现要好得多。现在,如果您需要使用列表进行其他操作,您可以同时使用它们。
var list = BuildListOfStrings();
var set = new HashSet<string>(list);
if (set.Contains("Test"))
{
// ...
}
现在,您可以在集合中查找O(1)
操作中的项目。
<强>测试强>
static void Main(string[] args)
{
var lst = GenerateStrings().Take(5000000).ToList();
var hsh = new HashSet<string>(lst);
var found = false;
var count = 100;
var sw = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
hsh = new HashSet<string>(lst);
}
Console.WriteLine(TimeSpan.FromTicks(sw.ElapsedTicks / count));
sw = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
found = lst.Contains("12345678");
}
Console.WriteLine(TimeSpan.FromTicks(sw.ElapsedTicks / count));
sw = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
found = hsh.Contains("12345678");
}
Console.WriteLine(TimeSpan.FromTicks(sw.ElapsedTicks / count));
Console.WriteLine(found);
Console.ReadLine();
}
private static IEnumerable<string> GenerateStrings()
{
var rnd = new Random();
while (true)
{
yield return rnd.Next().ToString();
}
}
<强>结果强>
0.308438 s 0.0197868 s 0.0 s
那么这告诉我们什么?如果您拨打少量电话Contains
,请使用List<string>
,否则请使用HashSet<string>
。