Другое событие NullPointerException
возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals
для гарантированного непустого объекта.
Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null
.
Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
LINQ напрямую поддерживает только эквисоединения. Если вы хотите выполнить какое-либо другое соединение, вам в основном потребуется перекрестное соединение и где
:
from a in tablea
from b in tableb
where a.col1 == b.col1 || a.col2 == b.col2
select ...
Вероятно, стоит проверить, как выглядит сгенерированный SQL и каков план запроса. Могут быть более эффективные способы сделать это, но это, вероятно, самый простой подход.
Возможно, стоит проверить, как выглядит сгенерированный SQL и каков план запроса. Могут быть более эффективные способы сделать это, но это, вероятно, самый простой подход. Возможно, стоит проверить, как выглядит сгенерированный SQL и каков план запроса. Могут быть более эффективные способы сделать это, но это, вероятно, самый простой подход.В зависимости от поставщика запроса вы можете просто использовать два предложения from:
from a in tablea
from b in tableb
where a.col1 == b.col1 || a.col2 == b.col2
Что, если вы выполняете в БД, будет столь же эффективным. Если вы выполняете в памяти (Linq to Objects), это перечислит все возможные комбинации, которые могут быть неэффективными.
Arg, Skeeted; -).
Возможны более эффективные альтернативы Linq to Objects. Оператор join
перечисляет каждый источник только один раз, а затем выполняет хэш-соединение, так что вы можете разделить предложение or на два отдельных соединения, а затем взять их объединение. Объединение в linq - это просто конкатенация без дубликатов, поэтому это будет выглядеть следующим образом:
(from a in tablea
join b in tableb on a.Col1 equals b.Col1
select new {a, b})
.Concat(
from a in tablea
join b in tableb on a.Col2 equals b.Col2
select new {a, b}
).Distinct()
Этот подход работает, и это всего лишь один запрос, но он несколько неочевиден в том смысле, что характеристики производительности кода зависят от понимания подробно как работает linq. Лично, если вы хотите выполнить хэш-соединение с потенциально множественными совпадениями, более очевидным инструментом является ToLookup
. Альтернативный вариант использования может выглядеть следующим образом:
var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 =
from a in tablea
from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
...
Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор ||
на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (например, использовать Distinct
).
(from a in tablea
join b in tableb on a.Col1 equals b.Col1
select new {a, b})
.Concat(
from a in tablea
join b in tableb on a.Col2 equals b.Col2
select new {a, b}
).Distinct()
Этот подход работает, и это всего лишь один запрос, но он несколько неочевиден в том смысле, что характеристики производительности кода зависят от детального понимания того, как работает linq. Лично, если вы хотите выполнить хэш-соединение с потенциально множественными совпадениями, более очевидным инструментом является ToLookup
. Альтернативный вариант использования может выглядеть следующим образом:
var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 =
from a in tablea
from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
...
Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор ||
на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (т.е. использовать Distinct
).
(from a in tablea
join b in tableb on a.Col1 equals b.Col1
select new {a, b})
.Concat(
from a in tablea
join b in tableb on a.Col2 equals b.Col2
select new {a, b}
).Distinct()
Этот подход работает, и это всего лишь один запрос, но он несколько неочевиден в том смысле, что характеристики производительности кода зависят от детального понимания того, как работает linq. Лично, если вы хотите выполнить хэш-соединение с потенциально множественными совпадениями, более очевидным инструментом является ToLookup
. Альтернативный вариант использования может выглядеть следующим образом:
var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 =
from a in tablea
from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
...
Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор ||
на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (т.е. использовать Distinct
).
ToLookup
. Альтернативный вариант использования может выглядеть следующим образом:
var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 =
from a in tablea
from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
...
Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор ||
на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (т.е. использовать Distinct
).
ToLookup
. Альтернативный вариант использования может выглядеть следующим образом:
var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 =
from a in tablea
from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
...
Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор ||
на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (т.е. использовать Distinct
).
var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 =
from a in tablea
from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
...
Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор ||
на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (например, использовать Distinct
).
var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 =
from a in tablea
from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
...
Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор ||
на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (т.е. использовать Distinct
).