Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
moosferatu
Jan 29, 2020
Maybe try a few and see what suits you best?

Personally, I use Intellij and highly recommend it. It has a ton of features, but I think some of the best are its static analysis and suggestions. It catches a lot of bugs that you might otherwise overlook. I hate to say it, but it's really clear when you open a file that was written by a developer in a different IDE, the average code quality and tidiness (mixed tabs and spaces in the same file! Ugh!) is notably worse. Not that IDE choice makes you a good or bad developer, but Intelllij offers features that make it easier to write better code. I would also recommend the SonarLint plugin.

Adbot
ADBOT LOVES YOU

hooah
Feb 6, 2006
WTF?
I agree with the IntelliJ recommendation. It also just looks nicer than Eclipse (but that'll be changing in a couple of quarters with a new UI for JetBrains' IDEs).

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider

hooah posted:

I agree with the IntelliJ recommendation. It also just looks nicer than Eclipse (but that'll be changing in a couple of quarters with a new UI for JetBrains' IDEs).

My understanding is that the new UI is optional and the old UI will continue to be available, which is good because that stripped down UI is not for me.

hooah
Feb 6, 2006
WTF?

RandomBlue posted:

My understanding is that the new UI is optional and the old UI will continue to be available, which is good because that stripped down UI is not for me.

Yeah, I watched their webcast on it and they said it'll be optional for users who are updating their IDEs for at least a year.

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider
If I wanted to use VS Code I'd use VS Code.

CPColin
Sep 9, 2003

Big ol' smile.
That was essentially my feedback I submitted, too (after "it stinks lmao")

hooah
Feb 6, 2006
WTF?
I've been trying it out in PyCharm and it's mostly been fine. Granted I'm not an actual Python dev, so I don't use it to the same extent that I use IntelliJ at work, but so far it's been good about surfacing tools as needed them and staying out of the way otherwise.

Clockwerk
Apr 6, 2005


Pulchritudinous posted:

Got directed here from the macOS/Mac software thread:

I got a new MBP and wanted to get back into tinkering with code (took some classes in school, but don't use any programming for work). I was wondering what the suggested IDEs are now. In class, we used Eclipse and I liked that that well enough (coming from no experience), but I wanted to see if there was something that was better suited to new hardware (rMBP vs. M1).

Edit: good lord, I butchered that

I think it largely depends on what language(s) you’re interested in working in.

VS Code seems to be the current go to for Javascript/Typescript, but also works well for C++ and Python, and the price is right.

IntelliJ for Java, hands down. Ultimate edition is great, but has a licensing cost. The community edition is free and still good.

If you’re doing Swift, I think your only choice is Xcode, but I could be wrong.

ivantod
Mar 27, 2010

Mahalo, fuckers.

Clockwerk posted:

If you’re doing Swift, I think your only choice is Xcode, but I could be wrong.

You're not wrong. The only real competitor, JetBrains AppCode has just been discontinued a few days ago: https://blog.jetbrains.com/appcode/2022/12/appcode-2022-3-release-and-end-of-sales-and-support/

Ihmemies
Oct 6, 2012

Is Java's formatter just weird or what, compared to ANSI C :D

Or is there some other way to specify "precision" than this hot garbage:

Java code:
System.out.println("#".repeat(col0_width + col1_width + ROW_PADDING));
for (var param : args) {                  
      System.out.printf("#%" + col0_width + "d | %-" + col1_width +"s #\n", i, param);
       i++;
       // avoid printing extra dividers
       if (i <= args.length) {
           System.out.printf("#%s+%s#\n",
                       "-".repeat(col0_width+1),
                       "-".repeat(col1_width+2));
        }
}
System.out.println("#".repeat(col0_width + col1_width + ROW_PADDING));
It prints out a table like this from command params. Specifying the precision/padding/whatever is just terrible... in C's printf you can do something like "%.*c", 17, '#' and then it prints 17 #'s.

Or "#%.d | #%.s #\n", col0_width, i, col1_width, param" instead of.. whatever you have to do with Java.

code:
#########################################
#  1 | Algeria                          #
#----+----------------------------------#
#  2 | Angola                           #
#----+----------------------------------#
#  3 | Benin                            #
#----+----------------------------------#
#  4 | Bolivia                          #
#----+----------------------------------#
#  5 | Chad                             #
#----+----------------------------------#
#  6 | Democratic Republic of the Congo #
#----+----------------------------------#
#  7 | Finland                          #
#----+----------------------------------#
#  8 | Lesotho                          #
#----+----------------------------------#
#  9 | Romania                          #
#----+----------------------------------#
# 10 | Uzbekistan                       #
#########################################
Not a big deal really but if they had to copy C why they didn't copy it properly :argh:

Ihmemies fucked around with this message at 18:30 on Jan 14, 2023

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider

Ihmemies posted:

Is Java's formatter just weird or what, compared to ANSI C :D

Or is there some other way to specify "precision" than this hot garbage:

Java code:
System.out.println("#".repeat(col0_width + col1_width + ROW_PADDING));
for (var param : args) {                  
      System.out.printf("#%" + col0_width + "d | %-" + col1_width +"s #\n", i, param);
       i++;
       // avoid printing extra dividers
       if (i <= args.length) {
           System.out.printf("#%s+%s#\n",
                       "-".repeat(col0_width+1),
                       "-".repeat(col1_width+2));
        }
}
System.out.println("#".repeat(col0_width + col1_width + ROW_PADDING));
It prints out a table like this from command params. Specifying the precision/padding/whatever is just terrible... in C's printf you can do something like "%.*c", 17, '#' and then it prints 17 #'s.

Or "#%.d | #%.s #\n", col0_width, i, col1_width, param" instead of.. whatever you have to do with Java.

code:
#########################################
#  1 | Algeria                          #
#----+----------------------------------#
#  2 | Angola                           #
#----+----------------------------------#
#  3 | Benin                            #
#----+----------------------------------#
#  4 | Bolivia                          #
#----+----------------------------------#
#  5 | Chad                             #
#----+----------------------------------#
#  6 | Democratic Republic of the Congo #
#----+----------------------------------#
#  7 | Finland                          #
#----+----------------------------------#
#  8 | Lesotho                          #
#----+----------------------------------#
#  9 | Romania                          #
#----+----------------------------------#
# 10 | Uzbekistan                       #
#########################################
Not a big deal really but if they had to copy C why they didn't copy it properly :argh:

I'd probably convert them to strings and use a utility function to pad the strings instead of the way you're doing it here.

Something like:

code:
System.out.printf("#%s | %s #\n", StringUtils.leftPad(i.toString(), col0_width), StringUtils.rightPad(param, col1_width));
More readable than what you have above or the C format IMO, no special knowledge of the formatter required other than %s.

e: Though if I were to want something like this I'd probably use one of the many libraries that do this type of thing along with printing out headers, etc...

RandomBlue fucked around with this message at 19:30 on Jan 14, 2023

Ihmemies
Oct 6, 2012

Thanks. It was a school exercise so I assume using the formatter was the idea behind it. Anyways, it is not good :( But I'll live. I've been doing an ANSI C course too so I got somewhat used to it.. just type what you want to be printed, then enter the list of variables separated by commas. Stringutils looks handy, thanks.

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider

Ihmemies posted:

Thanks. It was a school exercise so I assume using the formatter was the idea behind it. Anyways, it is not good :( But I'll live. I've been doing an ANSI C course too so I got somewhat used to it.. just type what you want to be printed, then enter the list of variables separated by commas. Stringutils looks handy, thanks.

It's part of this library, there are ton of good utility classes in here: https://commons.apache.org/proper/commons-lang/apidocs/overview-summary.html

Ihmemies
Oct 6, 2012

School exercises have progressed. I made a MovieAnalytics class, as instructed - using streams and Collectors.groupingBy. Automatic grading gave it a pass.

The three methods I implemented look like each other. The .collect method differrs, and sort has descending order in some.. also the printouts differ.

Does it make any sense to try to make some kind of combination of these three? The code looks repetitive, but does it matter?

If I "must" do some kind of combination method, how could I get started? I have no functioning ideas after trying. It gets too hard for me to choose elegantly between different groupingBy() methods with streams...

Also the .sorted() is not very good, but I could not figure out another way to sort those...

Java code:
/* 
    Member function void printCountByDirector(int n) that prints out the n directors that
    have directed the most movies, in descending order of the number of movies.
    Directors with equally many movies are ordered by their names using the
    default order of the String objects. Each director is printed in the ###m 
    "director: x movies", where x is the number of movies directed by that 
    particular director. The output is printed in a single line that ends 
    to a new line character.
    */
    public void printCountByDirector(int n) {
        movies.stream()
            .collect(Collectors.groupingBy(Movie::getDirector, Collectors.counting()))
            .entrySet()
            .stream()
            .sorted((e1, e2) -> {
                // sort by movie count descending    
                int countCompare = e2.getValue().compareTo(e1.getValue());                            
                if (countCompare != 0) {
                    return countCompare; 
                // IF movie count is equal, sort by director name ascending
                } 
                else {
                    return e1.getKey().compareTo(e2.getKey()); 
                }
            })
            .limit(n)
            .forEach(e -> System.out.print(e.getKey() + ": " + e.getValue() + " movies\n"));
    }


    /* 
    Member function void printAverageDurationByGenre() that prints out all movie genres of 
    the database in ascending order of the average duration of movies in that 
    genre. Movies in the same genre are ordered by title using the default order
    of the String objects. Each genre is printed in the ###m "genre: average",
    where average is the average duration of movies in that genre, using two 
    decimals of precision. The output is printed in a single line that ends
    to a new line character.
    */
    public void printAverageDurationByGenre() {
        movies.stream()
            .collect(Collectors.groupingBy(Movie::getGenre, Collectors.averagingDouble(Movie::getDuration)))
            .entrySet()
            .stream()
            .sorted((e1, e2) -> {
                // sort by movie average duration ascending    
                int countCompare = e1.getValue().compareTo(e2.getValue());                            
                if (countCompare != 0) {
                    return countCompare; 
                // IF movie average duration is equal, sort by genre name ascending
                } 
                else {
                    return e1.getKey().compareTo(e2.getKey()); 
                }
            })
            .forEach(e -> System.out.print(e.getKey() + ": " + String.format("%.2f", e.getValue()).replace(',', '.') + "\n"));
    }


    /*
    Member function void printAverageScoreByGenre() that prints out all movie
    genres of the database in descending order of the average rating scores
    of movies in that genre. Genres with the same average rating are ordered 
    by genre name using the default order of the String objects. Each genre 
    is printed in the ###m "genre: average", where average is the average
    rating score of movies in that genre, using two decimals of precision. 
    The output is printed in a single line that ends to a new line character.
    */
    public void printAverageScoreByGenre() {
        movies.stream()
            .collect(Collectors.groupingBy(Movie::getGenre, Collectors.averagingDouble(Movie::getScore)))
            .entrySet()
            .stream()
            .sorted((e1, e2) -> {
                // sort by movie count descending    
                int countCompare = e2.getValue().compareTo(e1.getValue());                            
                if (countCompare != 0) {
                    return countCompare; 
                // IF movie count is equal, sort by director name ascending
                } 
                else {
                    return e1.getKey().compareTo(e2.getKey()); 
                }
            })
            .forEach(e -> 
                System.out.print(
                    e.getKey() +
                    ": " + 
                    String.format("%.2f", e.getValue()).replace(',', '.') +
                     "\n"));
    }

Eezee
Apr 3, 2011

My double chin turned out to be a huge cyst
The only thing i would change is your sort method. You can do better using the built in Comparator functions. See:
https://www.baeldung.com/java-8-comparator-comparing

Refactoring other stuff there would just make it more complicated for marginally less repetition.

Ihmemies
Oct 6, 2012

Eezee posted:

The only thing i would change is your sort method. You can do better using the built in Comparator functions. See:
https://www.baeldung.com/java-8-comparator-comparing

Refactoring other stuff there would just make it more complicated for marginally less repetition.

Thanks, I found out about the Java8's Comparator comparing but I was too dense to understand how to use it. I will try again :v:

Clockwerk
Apr 6, 2005


Ihmemies posted:

Thanks, I found out about the Java8's Comparator comparing but I was too dense to understand how to use it. I will try again :v:

Comparators don’t feel intuitive to me either, so don’t feel bad. And they’re nice once you’ve got them working.

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

Talking about "refactoring" in the context of a school assignment is always hard because the (necessarily) limited size of the codebase makes it natural to write "right-size" functions anyways. I didn't really understand what good refactoring looks like until I was in a product codebase where the equivalents of those methods are hundreds of lines of basically the same code, and I wanted to ensure edits to duplicated parts of it didn't get forgotten in one or another, and I wanted to unit test parts of it, and so on and so forth.

Ihmemies
Oct 6, 2012

So finally we're doing some javafx-maven-whatever programs. The first is a very simple calculator. It is tested on school's black book CalculatorTest tester.

code:
Failures (2):
  JUnit Jupiter:CalculatorTest:Testing field basics
    MethodSource [className = 'fi.tuni.prog3.calc.CalculatorTest', methodName = 'checkFields', methodParameterTypes = '']
    => java.lang.ClassCastException: class javafx.scene.control.TextField cannot be cast to class javafx.scene.control.Label (javafx.scene.control.TextField and javafx.scene.control.Label are in unnamed module of loader java.net.FactoryURLClassLoader @6bdf28bb)
       fi.tuni.prog3.calc.CalculatorTest.checkFields(CalculatorTest.java:39)
       java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
       java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       java.base/java.lang.reflect.Method.invoke(Method.java:568)
       org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
       org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
       org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
       org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
       org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
       [...]
  JUnit Jupiter:CalculatorTest:Testing operations
    MethodSource [className = 'fi.tuni.prog3.calc.CalculatorTest', methodName = 'checkOperations', methodParameterTypes = '']
    => java.lang.ClassCastException: class javafx.scene.control.TextField cannot be cast to class javafx.scene.control.Label (javafx.scene.control.TextField and javafx.scene.control.Label are in unnamed module of loader java.net.FactoryURLClassLoader @6bdf28bb)
       fi.tuni.prog3.calc.CalculatorTest.checkOperations(CalculatorTest.java:102)
       java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
       java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       java.base/java.lang.reflect.Method.invoke(Method.java:568)
       org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
       org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
       org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
       org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
       org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
       [...]

Do you have any ideas what might cause that error? The app looks like this in Scene Builder:



I read the values like this on my controller class:

code:
String op1Str = fieldOp1.getText();
String op2Str = fieldOp2.getText();
Then I convert them to double, do calculations, convert back to String and write it to the result textfield:

code:
fieldRes.setText(result.toString());
It appears to be working correctly on my PC.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
It's not on your code. The crash is in the tester code. Do you have access to the tester source?

If I had to guess blind, I'd speculate that maybe the result field is supposed to be another label (instead of a textview that the user could type into themselves), but it's possible that it's not that and the tester itself is just poorly-written.

Ihmemies
Oct 6, 2012

Jabor posted:

It's not on your code. The crash is in the tester code. Do you have access to the tester source?

If I had to guess blind, I'd speculate that maybe the result field is supposed to be another label (instead of a textview that the user could type into themselves), but it's possible that it's not that and the tester itself is just poorly-written.

Welp gently caress, the idea was so stupid my brains just smoothed over it. It had to be a LABEL which LOOKS LIKE a text field... sigh. Thanks for the help! :v:

smackfu
Jun 7, 2004

Can you just tel them to stop teaching you poo poo no one uses?

Esran
Apr 28, 2008

Ihmemies posted:

Thanks, I found out about the Java8's Comparator comparing but I was too dense to understand how to use it. I will try again :v:

I figure you've probably discovered how these work by now, but in case you haven't, Comparator.comparing is actually pretty straight forward.

The method signature is

code:
static <T, U extends Comparable<? super U>>
Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)
This looks like a mess, but focus on the keyExtractor parameter. If you look at the definition of Function, the two types involved are T (the input) and U (the output). So keyExtractor is a function that takes a T and returns a U, and that U must implement Comparable.

The idea of the comparing method is that you can take a collection of things that don't implement Comparable and compare them anyway by extracting something from them that does implement Comparable.

So let's say I have a list of Humans, and I want to compare them by height. Rather than writing the Comparator by hand, I can do

code:
Comparator<Human> humanComparator = Comparator.comparing(human -> human.getHeight())
and get a Comparator that extracts the height (an Integer, which implements Comparable) from a Human. The height is then used for comparisons when you want to compare Humans. In this case my function's type T is Human, and my return type U is Integer.

One surprise you might encounter when using methods with generic parameters like this is that the left hand side of the assignment is important. Notice that it doesn't say anywhere on the right hand side that you're working with the Human type. If you were to just write something like
code:
Comparator.comparing(human -> human.getHeight())
it would not compile, because you haven't told Java which type the "human" parameter has.

The reason it works anyway when you do the assignment is because Java's compiler will look at the left hand side and see that you're making a Comparator<Human>, and so it infers that Comparator.comparing must return a Comparator<Human>, and therefore the "human" parameter must be a Human. This is called "target typing", and it also works for method parameters.

So you can do things like

code:
myHumanStream
.sorted(Comparator.comparing(human -> human.getHeight()))
The compiler knows that you're calling sorted on a Stream of Human, so it knows that the Comparator returned by the comparing function must be a Comparator<Human>, which it then uses to infer that the type of the "human" parameter is Human.

Ihmemies
Oct 6, 2012

smackfu posted:

Can you just tel them to stop teaching you poo poo no one uses?

It's hard. Anyways we got to do our own project now where we can do whatever we want. It pulls some jsons from a rest api over the internet, and we display some data in a javafx application.

Anyways, should vscode display tooltips and tell me more about the classes?

For example in our maven project:

ObjectMapper mapper = new ObjectMapper();

tooltips tell only:

com.fasterxml.jackson.databind.ObjectMapper.ObjectMapper()

Not very helpful. What is an ObjectMapper? Why the tooltip doesn't tell me anything about it? I have no idea should it show more, or is something just broken in my vscode.

If I right click and go to definition, it shows just this:

Java code:
 // Failed to get sources. Instead, stub sources have been generated by the disassembler.
 // Implementation of methods is unavailable.
package com.fasterxml.jackson.databind;
public class ObjectMapper extends com.fasterxml.jackson.core.ObjectCodec implements com.fasterxml.jackson.core.Versioned, java.io.Serializable {
  
  private static final long serialVersionUID = 2L;
  
  protected static final com.fasterxml.jackson.databind.AnnotationIntrospector DEFAULT_ANNOTATION_INTROSPECTOR;
  
  protected static final com.fasterxml.jackson.databind.cfg.BaseSettings DEFAULT_BASE;
  
  protected final com.fasterxml.jackson.core.JsonFactory _jsonFactory;
  
  protected com.fasterxml.jackson.databind.type.TypeFactory _typeFactory;
  
  protected com.fasterxml.jackson.databind.InjectableValues _injectableValues;
  
  protected com.fasterxml.jackson.databind.jsontype.SubtypeResolver _subtypeResolver;
  
  protected final com.fasterxml.jackson.databind.cfg.ConfigOverrides _configOverrides;
  
  protected final com.fasterxml.jackson.databind.cfg.CoercionConfigs _coercionConfigs;
  
  protected com.fasterxml.jackson.databind.introspect.SimpleMixInResolver _mixIns;
  
  protected com.fasterxml.jackson.databind.SerializationConfig _serializationConfig;
  
  protected com.fasterxml.jackson.databind.ser.DefaultSerializerProvider _serializerProvider;
  
  protected com.fasterxml.jackson.databind.ser.SerializerFactory _serializerFactory;
  
  protected com.fasterxml.jackson.databind.DeserializationConfig _deserializationConfig;
  
  protected com.fasterxml.jackson.databind.deser.DefaultDeserializationContext _deserializationContext;
  
  protected java.util.Set<java.lang.Object> _registeredModuleTypes;
  
  protected final java.util.concurrent.ConcurrentHashMap<com.fasterxml.jackson.databind.JavaType,com.fasterxml.jackson.databind.JsonDeserializer<java.lang.Object>> _rootDeserializers;
  
  public ObjectMapper() {
  }
Edit:

I had to go vscode settings -> search for download sources -> enable java > eclipse & java > maven download sources.

Then I had to go find my maven's settings.xml and add this (it was in some weird random folder in my C:\users\username\.m2\ folder.)

code:
<settings>
    <!-- ... other settings omitted ... -->
    <profiles>
        <profile>
            <id>downloadSources</id>
            <properties>
                <downloadSources>true</downloadSources>
                <downloadJavadocs>true</downloadJavadocs>
            </properties>
        </profile>
    </profiles>

    <activeProfiles>
            <activeProfile>downloadSources</activeProfile>
    </activeProfiles>
</settings>

Ihmemies fucked around with this message at 09:41 on Apr 22, 2023

Pedestrian Xing
Jul 19, 2007

I don't know VSCode specifically but most IDEs allow you to right click a dependency and download sources/docs. Most libraries also have their Javadocs and use guides online if you search.

Pedestrian Xing fucked around with this message at 21:37 on Apr 22, 2023

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider
Highly recommend IntelliJ IDEA Community Edition over VS Code for Java development. They have a VS Code-like UI available now if that's what you want.

hooah
Feb 6, 2006
WTF?

RandomBlue posted:

Highly recommend IntelliJ IDEA Community Edition over VS Code for Java development. They have a VS Code-like UI available now if that's what you want.

Agreed. I tried to use VS Code for Java at work for like a day and gave up. A real IDE (particularly one that's focused on the language you're using) is just so much better to work with, and JetBrains really know their poo poo.

Ihmemies
Oct 6, 2012

Qt, IntelliJ IDEA, Netbeans, Visual Studio just feel like "legacy" apps compared to VSCode. Like, I haven't even tested them myself, but that was my impression! I got the java documentation to work in vscode, so it was pretty nice after all. I don't know what I'm missing. What am I missing while using vscode instead of intellij idea for example?

As a student I don't really have money to pay for software, so vscode is nice in that respect too, since it's completely free and open source.



We coded a javafx app which pulls open data from REST API and displays our university's degree programmes and courses. You can add and remove courses and mark them as completed, and it shows your progression. Supports multiple users (for no real benefit). Took maybe 2 weeks of coding from three guys. We didn't make a spec first, so it was kind of uhh "let's try if this works" approach. Worked well enough.

hooah
Feb 6, 2006
WTF?
In my (limited) experience, VS Code requires at least a few plugin to get it working for Java, then you have to write your own run commands or whatever. IntelliJ, even the community edition, understands how to run and debug Java programs out of the box, and makes it very easy to do so.

Ihmemies
Oct 6, 2012

hooah posted:

In my (limited) experience, VS Code requires at least a few plugin to get it working for Java, then you have to write your own run commands or whatever. IntelliJ, even the community edition, understands how to run and debug Java programs out of the box, and makes it very easy to do so.

I installed some set of Java tools which vscode suggested. They seemed to work fine, except for the documentation issue, Maven didn't know how to download docs automatically. Only missing debugger feature was that it would be nice to have some kind of "developer mode" in javafx where you can "inspect" elements in the javafx app, like in a webpage in a browser or something. There was some maven plugin for that but it hadn't been updated in years and supported only ancient java versions.

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Ihmemies posted:

I installed some set of Java tools which vscode suggested. They seemed to work fine, except for the documentation issue, Maven didn't know how to download docs automatically. Only missing debugger feature was that it would be nice to have some kind of "developer mode" in javafx where you can "inspect" elements in the javafx app, like in a webpage in a browser or something. There was some maven plugin for that but it hadn't been updated in years and supported only ancient java versions.

IntelliJ just works so well out of the box. I would ditch VSCode for Java development so you don't have to waste time trying to get it to do what IntelliJ does by default. The Community Edition is also free.

Ihmemies
Oct 6, 2012

fletcher posted:

IntelliJ just works so well out of the box. I would ditch VSCode for Java development so you don't have to waste time trying to get it to do what IntelliJ does by default. The Community Edition is also free.

I have no idea when school will force more java for us, so I have no idea when I will do more java coding. Maybe never? My vscode is set up now, so what is the point of changing and learning to use some new tool? Just because it's new and fancy is not a good enough reason.

moosferatu
Jan 29, 2020

Ihmemies posted:

Qt, IntelliJ IDEA, Netbeans, Visual Studio just feel like "legacy" apps compared to VSCode.

Ihmemies posted:

Just because it's new and fancy is not a good enough reason.

I can promise you that intellij is by far the best java ide. I currently work on a large legacy code base that has been worked on over the years using NetBeans, Eclipse, VSCode, and Intellij. Sadly, it is blindly obvious which contributions were not authored in intellij.

But, you should totally use the editor that suits you best. There is a lot to be said for sticking with the editor you know and use for all of your other work rather than learning a new tool.

Ihmemies
Oct 6, 2012

I tried searching for reasons why IntelliJ is better, but I could not find a single concrete example on why it is better. Even better would be a list of benefits with concrete examples. Surely someone must have made one?

Or maybe even a list of what’s missing from vscode, and why the missing feature matters? Even chatgpt could not give answers.

Volguus
Mar 3, 2009

Ihmemies posted:

I tried searching for reasons why IntelliJ is better, but I could not find a single concrete example on why it is better. Even better would be a list of benefits with concrete examples. Surely someone must have made one?

Or maybe even a list of what’s missing from vscode, and why the missing feature matters? Even chatgpt could not give answers.

At the end of the day, use whatever works for you. With that being said, having experience with more than one editor/IDE is important. Why?

1. It's a new skill. It's not going to take a lifetime to learn an IDE. The amount of time you would spend on it will be more than paid back when at an interview you can confidently say: "I have used IntelliJ/Eclipse/Netbeans/VSCode".
2. You can make up your own mind as to what you personally like or dislike (I personally like Eclipse, I can stand IntelliJ but not prefer it. I have had years, many, of experience with both. I'm not a fan of VSCode, though I am using it at work now for C++, but it can be very powerful when configured properly).
3. You can yourself offer arguments later to others on why you like X vs Y.

However, if you don't think (or don't want) to use Java in the future, ever, then this discussion is pointless. My opinion is that having a new skill is better than not.

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider
Don't you come in here smack talking IntelliJ, rookie.

HamAdams
Jun 29, 2018

yospos
out of the box code navigation and completion is so much better in intellij than vscode, which is a huge deal when i’m working in a large codebase. you might be able to come close using a bunch of plugins, but i’d much rather spend my free time drinking coffee and slacking off instead of janitoring my config files

Soricidus
Oct 21, 2010
freedom-hating statist shill
the new ui option in intellij even makes it look and feel more like vscode. it’s good

for inspect-element style visual debugging of javafx guis you want scenic-view, it’s a standalone app so you can use it alongside whatever ide you prefer

Paul MaudDib
May 3, 2006

TEAM NVIDIA:
FORUM POLICE
there has to be a way to tie spring bean qualifiers/names into an arbitrary data access schema, right? something like being able to generate a bean with an @Qualifier that's the name of the resource file it's stored in?

I was reading this awesome little corner of spring and I realized that this is cool and all but what it really needs is the ability to specify an arbitrary builder which can programmatically dump in some builder sequence that comes out of a database or some other format, so the inner platform can be completed.

and then I started thinking like what if you could just define any primary key in a database (or composite key for a query etc) as the configuration identifier, and have spring construct a configuration bean that's actually your data item and inject it into some bean as desired by some other instantiation? like a "queryresult" bean (or a frontend model) where the actual query execution and assembly for a ResponseBean is guided by spring IOC.

extremely Cool and Good thoughts basically

https://ozdinc-celikel.medium.com/distributed-state-machines-using-java-spring-state-machine-framework-e9ff9655c486
code:
@Configuration                       
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<States, Events> {...}

@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
        throws Exception {
            transitions
            .withExternal()
            .source(States.UNPAID).
             target(States.WAITING_FOR_RECEIVE)
            .event(Events.PAY)
            .action(transitionAction())
            
            .and()
            
            .withExternal()
            .source(States.WAITING_FOR_RECEIVE)
            .target(States.DONE)
            .event(Events.RECEIVE)
            .action(transitionAction())
            
            .and()
            
            .withExternal()
            .source(States.DONE).target(States.UNPAID)
            .event(Events.STARTFROMSCRATCH)
            .action(transitionAction());
}

Paul MaudDib fucked around with this message at 09:36 on Jul 8, 2023

Adbot
ADBOT LOVES YOU

Ornedan
Nov 4, 2009


Cybernetic Crumb
I'm trying to figure out the fastest way to reverse way to reverse bits in a byte.

For context I'm trying to make some graphics stuff (dithering) go really fast and I finally hit a point where writing pixels through the whole BufferedImage, ColorModel, Raster, SampleModel and DataBuffer sequence dominates the per-pixel time. So it's time to write specialised code for common combinations that fucks directly with the image bits and chop off another 50% of time required.

Ways to reverse bits I've found and tried so far:

Java code:
import java.util.Random;
import java.util.function.Function;

public class ReverseBitsInByteTest
{
  public static byte reverseStdlib(byte b)
  {
    return (byte)(Integer.reverse(b & 0xFF) >> 24);
  }

  public static byte reverseSwaps(byte b)
  {
    int r = (b & 0b11110000) >> 4 | (b & 0b00001111) << 4;
    r     = (r & 0b11001100) >> 2 | (r & 0b00110011) << 2;
    r     = (r & 0b10101010) >> 1 | (r & 0b01010101) << 1;

    return (byte)r;
  }

  private static final int[] lookupReverseNybble =
  {
    0x0,0x8,0x4,0xc,0x2,0xa,0x6,0xe,0x1,0x9,0x5,0xd,0x3,0xb,0x7,0xf,
  };

  public static byte reverseNybbles(byte b)
  {
    return (byte)((lookupReverseNybble[b & 0b00001111] << 4) | lookupReverseNybble[(b & 0b11110000) >> 4]);
  }

  private static final int[] lookupReverseByte =
  {
    0x0,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,
    0xf0,0x8,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,0x18,0x98,0x58,0xd8,0x38,0xb8,
    0x78,0xf8,0x4,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,0x14,0x94,0x54,0xd4,0x34,
    0xb4,0x74,0xf4,0xc,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,0x1c,0x9c,0x5c,0xdc,
    0x3c,0xbc,0x7c,0xfc,0x2,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,0x12,0x92,0x52,
    0xd2,0x32,0xb2,0x72,0xf2,0xa,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,0x1a,0x9a,
    0x5a,0xda,0x3a,0xba,0x7a,0xfa,0x6,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,0x16,
    0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,0xe,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,
    0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,0x1,0x81,0x41,0xc1,0x21,0xa1,0x61,
    0xe1,0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,0x9,0x89,0x49,0xc9,0x29,0xa9,
    0x69,0xe9,0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,0x5,0x85,0x45,0xc5,0x25,
    0xa5,0x65,0xe5,0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,0xd,0x8d,0x4d,0xcd,
    0x2d,0xad,0x6d,0xed,0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,0x3,0x83,0x43,
    0xc3,0x23,0xa3,0x63,0xe3,0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,0xb,0x8b,
    0x4b,0xcb,0x2b,0xab,0x6b,0xeb,0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,0x7,
    0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
    0xf,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,
    0xff,
  };

  public static byte reverseLookup(byte b)
  {
    return (byte)lookupReverseByte[b & 0xFF];
  }

  /** http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv */
  public static byte reverseBithack3(byte b)
  {
    return (byte)((((b & 0xFF) * 0x0202020202l) & 0x010884422010l) % 1023);
  }

  /** http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits */
  public static byte reverseBithack4(byte b)
  {
    return (byte)((((b & 0xFF) * 0x80200802l) & 0x0884422110l) * 0x0101010101l >> 32);
  }


  public static String toPaddedBinStr(int b, int pad)
  {
    String str = Integer.toBinaryString(b);
    while(str.length() < pad)
      str = '0' + str;
    return str;
  }

  public static String toPaddedBinStr(long b, int pad)
  {
    String str = Long.toBinaryString(b);
    while(str.length() < pad)
      str = '0' + str;
    return str;
  }

  public static void check(String name,Function<Byte,Byte> func)
  {
    for(int b = 0; b <= 0xFF; b++)
    {
      int rev = func.apply((byte)b) & 0xFF;
      String binStr = toPaddedBinStr(b,8);
      String revStr = toPaddedBinStr(rev,8);
      boolean correct =
        new StringBuilder(binStr).reverse().toString().equals(revStr);

      if( !correct)
        System.out.printf("%s failed: %s => %s\n",name,binStr,revStr);
    }
  }

  public static void main(String[] args) throws Throwable
  {
    // Correctness checks
    check("reverseStdlib",ReverseBitsInByteTest::reverseStdlib);
    check("reverseSwaps",ReverseBitsInByteTest::reverseSwaps);
    check("reverseNybbles",ReverseBitsInByteTest::reverseNybbles);
    check("reverseLookup",ReverseBitsInByteTest::reverseLookup);
    check("reverseBithack3",ReverseBitsInByteTest::reverseBithack3);
    check("reverseBithack4",ReverseBitsInByteTest::reverseBithack4);

    // Speed testing
    byte[] data = new byte[1000000];
    new Random().nextBytes(data);

    long beginStdlib = System.currentTimeMillis();
    for(int repeats = 0; repeats < 1000; repeats++)
      for(int i = 0; i < data.length; i++)
        data[i] = reverseStdlib(data[i]);
    long endStdlib = System.currentTimeMillis();

    long beginSwaps = System.currentTimeMillis();
    for(int repeats = 0; repeats < 1000; repeats++)
      for(int i = 0; i < data.length; i++)
        data[i] = reverseSwaps(data[i]);
    long endSwaps = System.currentTimeMillis();

    long beginNybbles = System.currentTimeMillis();
    for(int repeats = 0; repeats < 1000; repeats++)
      for(int i = 0; i < data.length; i++)
        data[i] = reverseNybbles(data[i]);
    long endNybbles = System.currentTimeMillis();

    long beginLookup = System.currentTimeMillis();
    for(int repeats = 0; repeats < 1000; repeats++)
      for(int i = 0; i < data.length; i++)
        data[i] = reverseLookup(data[i]);
    long endLookup = System.currentTimeMillis();

    long beginBithack3 = System.currentTimeMillis();
    for(int repeats = 0; repeats < 1000; repeats++)
      for(int i = 0; i < data.length; i++)
        data[i] = reverseBithack3(data[i]);
    long endBithack3 = System.currentTimeMillis();

    long beginBithack4 = System.currentTimeMillis();
    for(int repeats = 0; repeats < 1000; repeats++)
      for(int i = 0; i < data.length; i++)
        data[i] = reverseBithack4(data[i]);
    long endBithack4 = System.currentTimeMillis();


    System.out.printf("Stdlib:   %d msec\n",endStdlib - beginStdlib);
    System.out.printf("Swaps:    %d msec\n",endSwaps - beginSwaps);
    System.out.printf("Nybbles:  %d msec\n",endNybbles - beginNybbles);
    System.out.printf("Lookup:   %d msec\n",endLookup - beginLookup);
    System.out.printf("Bithack3: %d msec\n",endBithack3 - beginBithack3);
    System.out.printf("Bithack4: %d msec\n",endBithack4 - beginBithack4);
  }
}

The weird thing I'm running into is that I get completely different results depending on whether that test class is compiled with javac on command line or Eclipse:

pre:
javac               | Eclipse
--------------------|--------------------
Stdlib:   1736 msec | Stdlib:   1661 msec
Swaps:    3528 msec | Swaps:    1531 msec
Nybbles:  2829 msec | Nybbles:  780 msec
Lookup:   2366 msec | Lookup:   459 msec
Bithack3: 3513 msec | Bithack3: 1087 msec
Bithack4: 2810 msec | Bithack4: 586 msec
Are these some optimisation flags Eclipse enables by default that could cause the difference?

e: oh wtf, whichever is the first one I measure time for is as fast in the javac-compiled bytecode as in Eclipse-compiled. So the javac results change if I reorder the speed tests.

Ornedan fucked around with this message at 15:03 on Jul 9, 2023

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply