Java Rules: “collect” should be used with “Streams” instead of “list::add”

While you can use either forEach(list::add) or collect with a Streamcollect is by far the better choice because it’s automatically thread-safe and parallellizable.

Noncompliant Code Example

List<String> bookNames = new ArrayList<>();
books.stream().filter(book -> book.getIsbn().startsWith("0"))
                .map(Book::getTitle)
                .forEach(bookNames::add);  // Noncompliant

Compliant Solution

List<String> bookNames = books.stream().filter(book -> book.getIsbn().startsWith("0"))
                .map(Book::getTitle)
                .collect(Collectors.toList());
Advertisements

IntelliJ Idea Üzerine Java Kural Yönlendiricisi Eklemek

SonarQube üzerinde çok faydalı bir blog bulunuyor. Bu blogda bir çok dil için hatalı yazım örnekleri, yanlış bilinen doğrular, bug’lar ve güvenlik açıkları hakkında bilgiler verilmiş. Verilen bilgilerin yanında hatalı durum ve ilgili durumun doğru yazımı için örnekler de bulunuyor.

Ayrıca bazı kurallarda kurala ilişkin kaynak referans da belirtiliyor. Ansiklopedi düzeyinde bilgi havuzu edinmek için güzel bir kaynak.

https://rules.sonarsource.com/java

SonarQube ekibi intelliJ idea ide’si için SonarLint adında bir de interaktif code analyzer add-on geliştirmiş. Bu eklenti ide üzerinde yazılı kodu inceliyor ve kural seti üzerinde eşleşen şüpheli durumlar için öneriler sunuyor.

Aktif olarak kullanılabilecek güzel bir eklenti.

https://www.sonarsource.com/products/codeanalyzers/sonarjava.html

Aşağıda konuya ilişkin ekran görüntüleri paylaşıyorum.

SonarLint eklentisinin intellij idea ide üzerinde kurulum örneği
SonarLint eklentisinin intellij idea ide üzerinde kurulum örneği
Intellij idea ide üzerinde sonarlint eklentisi, hata durumunda ilgili kodun arkaplanını belirginleştiriyor. Ctrl+f1 ile ilgili sonarlint rule suggestion'ını okuyabilirsiniz. Yada ide'nin sonarlint penceresinde önerileri görüntüleyebilirsiniz.
Intellij idea ide üzerinde sonarlint eklentisi, hata durumunda ilgili kodun arkaplanını belirginleştiriyor. Ctrl+f1 ile ilgili sonarlint rule suggestion’ını okuyabilirsiniz. Yada ide’nin sonarlint penceresinde önerileri görüntüleyebilirsiniz.
sonarlint-intellij-window-rule-description
sonarlint intellij penceresi ve kural açıklaması

Java Rules: “Collections.EMPTY_LIST”, “EMPTY_MAP”, and “EMPTY_SET” should not be used

Since the introduction of generics in Java 5, the use of generic types such as List<String> is recommended over the use of raw ones such as List. Assigning a raw type to a generic one is not type safe, and will generate a warning. The old EMPTY_... fields of the Collections class return raw types, whereas the newer empty...() methods return generic ones.

Noncompliant Code Example

List<String> collection1 = Collections.EMPTY_LIST;  // Noncompliant
Map<String, String> collection2 = Collections.EMPTY_MAP;  // Noncompliant
Set<String> collection3 = Collections.EMPTY_SET;  // Noncompliant

Compliant Solution

List<String> collection1 = Collections.emptyList();
Map<String, String> collection2 = Collections.emptyMap();
Set<String> collection3 = Collections.emptySet();

Java Rules: “Arrays.stream” should be used for primitive arrays

For arrays of objects, Arrays.asList(T ... a).stream() and Arrays.stream(array) are basically equivalent in terms of performance. However, for arrays of primitives, using Arrays.asList will force the construction of a list of boxed types, and then use that last as a stream. On the other hand, Arrays.stream uses the appropriate primitive stream type (IntStreamLongStreamDoubleStream) when applicable, with much better performance.

Noncompliant Code Example

Arrays.asList("a1", "a2", "b1", "c2", "c1").stream()
    .filter(...)
    .forEach(...);

Arrays.asList(1, 2, 3, 4).stream() // Noncompliant
    .filter(...)
    .forEach(...);

Compliant Solution

Arrays.asList("a1", "a2", "b1", "c2", "c1").stream()
    .filter(...)
    .forEach(...);

int[] intArray = new int[]{1, 2, 3, 4};
Arrays.stream(intArray)
    .filter(...)
    .forEach(...);

Java Rules: “.equals()” should not be used to test the values of “Atomic” classes

AtomicInteger, and AtomicLong extend Number, but they’re distinct from Integer and Long and should be handled differently. AtomicInteger and AtomicLong are designed to support lock-free, thread-safe programming on single variables. As such, an AtomicInteger will only ever be “equal” to itself. Instead, you should .get() the value and make comparisons on it.

This applies to all the atomic, seeming-primitive wrapper classes: AtomicIntegerAtomicLong, and AtomicBoolean.

Noncompliant Code Example

AtomicInteger aInt1 = new AtomicInteger(0);
AtomicInteger aInt2 = new AtomicInteger(0);

if (aInt1.equals(aInt2)) { ... }  // Noncompliant

Compliant Solution

AtomicInteger aInt1 = new AtomicInteger(0);
AtomicInteger aInt2 = new AtomicInteger(0);

if (aInt1.get() == aInt2.get()) { ... }

Java Rules: “for” loop stop conditions should be invariant

for loop stop condition should test the loop counter against an invariant value (i.e. one that is true at both the beginning and ending of every loop iteration). Ideally, this means that the stop condition is set to a local variable just before the loop begins.

Stop conditions that are not invariant are slightly less efficient, as well as being difficult to understand and maintain, and likely lead to the introduction of errors in the future.

This rule tracks three types of non-invariant stop conditions:

  • When the loop counters are updated in the body of the for loop
  • When the stop condition depend upon a method call
  • When the stop condition depends on an object property, since such properties could change during the execution of the loop.

Noncompliant Code Example

for (int i = 0; i < 10; i++) {
  ...
  i = i - 1; // Noncompliant; counter updated in the body of the loop
  ...
}

Compliant Solution

for (int i = 0; i < 10; i++) {...}

See

  • MISRA C:2004, 13.6 – Numeric variables being used within a for loop for iteration counting shall not be modified in the body of the loop.
  • MISRA C++:2008, 6-5-3 – The loop-counter shall not be modified within condition or statement.