10 Best IntelliJ IDEA Plugins That Will Boost Your Productivity
Source:
Hackernoon I recently asked developers who use IntelliJ IDEA what plugins they like best for this IDE? Based on the collected responses, a list of the 10 most popular extensions was obtained.
1. WakaTime
WakaTime allows you to see metrics, analytics, and track time spent programming. With it, you'll know exactly how much time you spend coding as the plugin automatically tracks when you start and stop typing, with detailed metrics for projects, file, branch, commit/PR, feature, and more.
2.Stepsize
This plugin helps in resolving issues related to technical debt, maintenance, and code refactoring. Stepsize allows you to:
- make bookmarks in the code;
- track technical debt directly from the editor;
- create TODO;
- prioritize technical issues during sprint planning;
- Collaborate with teammates during code maintenance and refactoring.
3. Key Promoter X
Key Promoter X helps you learn the meaning of shortcuts and buttons in IntelliJ IDEA. When you hover your mouse over a button inside the IDE, Key Promoter X shows you a keyboard shortcut that you can use instead of clicking the mouse.
4. ZIO for IntelliJ
ZIO will provide you with suggestions, refactorings and other improvements for the Scala ZIO ecosystem. The plugin extends the ZIO library with functions such as:
- refactorings and suggestions;
- support for zio macros (for example, @accessible);
- built-in test run.
5.Protobuf
The Protobuf Language plugin for IntelliJ-based IDEs provides support for the Protobuf language. Protobuf helps with syntax highlighting, importing files from the library and SDK, navigation, code folding, semantic analysis, and quick documentation.
6.SonarLint
SonarLint allows you to fix code problems before they happen. As a spell checker, SonarLint highlights errors and security vulnerabilities as you write code, with clear instructions on how to fix them, so you can fix them before the code is committed. SonarLint in VS Code supports code analysis in Java, JavaScript, TypeScript, Python, HTML and PHP.
7. ESLint
ESLint supports displaying eslint warnings as IntelliJ inspections, helps perform quick fixes for multiple rules, supports custom eslint rules, and eslint configuration annotation and completion.
8. Prettier
The Prettier extension helps your code look better and be more consistent. It ensures a consistent style by analyzing your code and rewriting it according to its rules and maximum line length.
9.Quokka
Quokka.js is a developer productivity tool for JavaScript/TypeScript rapid prototyping. In the IDE, it updates the execution time metric next to the code as you type. This greatly speeds up prototyping, training, and testing of JavaScript/TypeScript.
10. AceJump
AceJump allows you to quickly move the cursor to any position visible in the editor. Simply press “CRTL+;”, enter a character, then enter the corresponding character for Ace Jump. If no matches are found on the screen, AceJump will move on to the next match it can find.
Handling exceptions in Java Streams using the functional interface
Source:
Dev.to I was recently looking through some code and came across something like this:
subject.getIdentities().forEach(i -> {
try {
caseService.updateDocument(i.getCase());
} catch (Exception e) {
log.error(e);
}
});
Since I'm a big fan of lambda expressions and love brevity, the above code seems a little concise and a bit confusing to me. To clear it, you should use functional interfaces. What do we need for this? We know that
forEach expects the Consumer input. If we could wrap our exception handling logic in a Consumer, then we could then use the logic in forEach. The main logic inside forEach is the following line:
i -> caseService.updateDocument(i.getCase());
We know the input and return type, and we can create a functional interface whose method throws an exception.
@FunctionalInterface
public interface ThrowingFunction<Identity, UpdateResponse> {
UpdateResponse apply(Identity i) throws Exception;
}
We can make the code even more convenient using generics.
@FunctionalInterface
public interface ThrowingFunction<T, R> {
R apply(T t) throws Exception;
}
Once the interface is created, the original logic can become typed:
ThrowingFunction<Identity, UpdateResponse> tf = i -> caseService.updateDocument(i.getCase());
Now that we have a functional interface for our logic, we can pass it as a parameter to a method that handles the exception and returns a Consumer that we can use in forEach.
private static <T, R> Consumer<T> wrap(ThrowingFunction<T, R> f) {
return t -> {
try {
f.apply(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
}
It looks a little strange, but essentially the wrap method takes a ThrowingFunction as input and handles the execution of the function or catches and throws exceptions in the Consumer. Now we can wrap any used logic in forEach that might throw an exception. It looks something like this:
ThrowingFunction<Identity, UpdateResponse> tf = i -> caseService.updateDocument(i.getCase()):
Consumer<Identity> p = wrap(tf);
subject.getIdentities().forEach(p);
Or if you prefer one line:
subject.getIdentities().forEach(wrap(i -> caseService.updateDocument(i.getCase())));
Agree that this is much better! You could implement something like this to handle different types of functional interfaces. For example, the
Map operation takes only a Function as input . Instead of a wrapper method returning a Consumer, you could have a method returning a function. This is just one way to handle exceptions in threads. I should mention that there are
libraries that do this for you. You can also use a monad to handle successes or failures, but that is beyond the scope of this post.