java – Why do I actually need an interface in Spring Boot?

When programming in Spring/Spring Boot, it’s a common practice to have every service/component implement an interface, for example:

public interface IAdder {
    int add(int a, int b);
}

@Service
public class Adder implements IAdder {
    public int add(int a, int b) { return a + b; }
}

Why do I actually need to write that interface if I don’t plan on having multiple implementations for “Adder” functionality?

One common answer to that question is “you’ll need it for mocking in your unit tests”. To that, I can answer – not really. I can mock the adder using every possible mocking framework you can think of (Mockito, for example):

@Autowired
IMultiplier multiplier;  // Class under test

@Mock
IAdder adder;

@Test
public void multiplicationTest() {
    // Arrange
    when(adder).add(3, 3).thenReturn(6);
    
    // Act
    int result = multiplier.multiply(3, 5);
    
    // Assert
    verify(adder, times(4)).add(3, 3);
    assertThat(result).isEqualTo(15);
}

Having said that, what advantage can the IAdder interface provide for me?

php – Pegar dados de um Banco de Dados Mysqli no Java Script

Estou desenvolvendo um simulador usando php e os cálculos em javaScript. Coisa bem simples. O cliente escolhe o valor que quer contratar, escolhe a quantidade de parcelas e o sistema retorna o valor das parcelas e o quanto ela pagará de juros. Para cada parcela clicada eu tenho um valor de taxa que vem diretamente do banco de dados, porém para fazer o cálculo eu estou inserindo de forma “engessada” os dados, pois não sei uma forma de pegar os valores diretamente do BD através do JavaScript. Meu código está assim hoje. Arquivo script.js

$(document).ready(function(){
    $('.mask-money').mask("#.##0,00", {reverse: true});
});

$('input(type=radio)(name=parcela)').on('click', function(){
    var inputParcelas = $('#valorParcelaBD').val($('input(type=radio)(name=parcela):checked').val())
    var qtdyParcelaBD = $('#qtdyParcelaBD').val($('input(type=radio)(name=parcela):checked').attr('id'))
    var valorSolicitado = Number($('#valorSolicitado').val().replace(/(^d)+/g,''))
    var parcelasclick = parseFloat($('input(type=radio)(name=parcela):checked').val());
    if(parcelasclick == 1) {
        var prazo = 1
    } else if(parcelasclick == 2) {
        var prazo = 2
    } else if(parcelasclick == 10.172047)// Preciso pegar esse valor de uma coluna de uma tabela no Banco de Dados {
        var prazo = 3 // Preciso pegar esse valor de uma coluna de uma tabela no Banco de Dados
    } else if(parcelasclick == 8.457329)//Preciso pegar esse valor dinamicamente de uma tabela no Banco de Dados{
        var prazo = 4// Preciso pegar esse valor de uma coluna da mesma tabela no Banco de Dados 
    } else if(parcelasclick == 7.322438)//Preciso pegar esse valor dinamicamente de uma tabela no Banco de Dados  {
        var prazo = 5 // Preciso pegar esse valor dinamicamente de uma tabela no Banco de Dados
    } else if(parcelasclick == 6.515287) {
        var prazo = 6// Preciso pegar esse valor dinamicamente de uma tabela no Banco de Dados 
    } else if(parcelasclick == 5.91142)//Preciso pegar esse valor dinamicamente de uma tabela no Banco de Dados {
        var prazo = 7//Preciso pegar esse valor dinamicamente de uma tabela no Banco de Dados
    } else if(parcelasclick == 5.442319)//Preciso pegar esse valor dinamicamente de uma tabela no Banco de Dados {
        var prazo = 8//Preciso pegar esse valor dinamicamente de uma tabela no Banco de Dados
    } else if(parcelasclick == 5.067154) {
        var prazo = 9
    } else if(parcelasclick == 4.760078) {
        var prazo = 10
    } else if(parcelasclick == 4.503933) {
        var prazo = 11
    } else if(parcelasclick == 4.28688403) {
        var prazo = 12
    } else if(parcelasclick == 4.1005) {
        var prazo = 13
    } else if(parcelasclick == 3.938613) {
        var prazo = 14
    } else if(parcelasclick == 3.796609) {
        var prazo = 15
    } else if(parcelasclick == 3.670964) {
        var prazo = 16
    } else if(parcelasclick == 3.558944) {
        var prazo = 17
    } else if (parcelasclick == 3.4264882) {
        var prazo = 18
    }
    var juros = (parcelasclick / 100) 
    var parcela = (valorSolicitado * juros) / (1 - Math.pow(1 / (1 + juros), prazo))
    var total = parcela * prazo;
    console.log('Input Parcelas: ' +inputParcelas)
    console.log('Valor Solicitado: ' +(valorSolicitado/ 100).toFixed(2))
    console.log('Taxa de Juros aplicada: ' +juros)
    console.log('Valor das Parcelas: '+(parcela/100).toFixed(2))
    console.log('Prazo: ' +(prazo).toFixed(2))
    console.log('Total ' +(total / 100).toFixed(2))
   
    $('#limiteNecessario').val((total / 100).toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' }));
    $('#valorParcela').val((parcela / 100).toLocaleString("pt-BR", { minimumFractionDigits: 2 , style: 'currency', currency: 'BRL' }));
    
});

socket – Redirecionamento de Porta Cling Java

Olá, estou tentando fazer o redirecionamento de porta no meu roteador de forma automática. Para isso, estou utilizando o Cling 2.1.2 no Java.
Meu código:

package teste_cling;

import java.net.ServerSocket;
import java.net.Socket;

import org.fourthline.cling.UpnpService;
import org.fourthline.cling.UpnpServiceImpl;
import org.fourthline.cling.support.igd.PortMappingListener;
import org.fourthline.cling.support.model.PortMapping;

public class RedirecionamentoPortas {
    private static final int PORTA = 3322;
    
    public static void main(String() args) {
        PortMapping mapeamento = new PortMapping(PORTA, "192.168.0.3", PortMapping.Protocol.TCP, "Redirecionamento de Porta TCP");
        UpnpService servicoUPnP = new UpnpServiceImpl(new PortMappingListener(mapeamento));            
        servicoUPnP.getControlPoint().search();

         try(ServerSocket servidor = new ServerSocket(PORTA);
             Socket cliente = servidor.accept()) {
             System.out.println("nO cliente " + cliente.getInetAddress().getHostAddress() + " se conectou."); 
         }
         catch(Exception excecao) {
             System.err.println(excecao.getMessage());
         }
         
         servicoUPnP.shutdown();
    }
}

Estou me baseando neste exemplo do próprio Cling.
O código compila e executa, mas não consigo me conectar remotamente (em outra rede) com o servidor na porta indicada.
Para testar se a porta está aberta ou fechada, estou utilizando este site.
Não configurei o redirecionamento no meu roteador, mas o UPnP está habilitado:
inserir a descrição da imagem aqui
O meu computador precisa estar conectado por cabo no roteador para que a configuração remota do Cling seja executada? Ou é a mesma coisa de estar conectado por wi-fi? Testei dos dois jeitos e não funcionou.
Saída do programa:

abr 21, 2021 1:15:52 AM org.fourthline.cling.UpnpServiceImpl <init>
INFORMAÇÕES: >>> Starting UPnP service...
abr 21, 2021 1:15:52 AM org.fourthline.cling.UpnpServiceImpl <init>
INFORMAÇÕES: Using configuration: org.fourthline.cling.DefaultUpnpServiceConfiguration
abr 21, 2021 1:15:52 AM org.fourthline.cling.transport.RouterImpl <init>
INFORMAÇÕES: Creating Router: org.fourthline.cling.transport.RouterImpl
abr 21, 2021 1:15:53 AM org.fourthline.cling.transport.impl.MulticastReceiverImpl init
INFORMAÇÕES: Creating wildcard socket (for receiving multicast datagrams) on port: 1900
abr 21, 2021 1:15:53 AM org.fourthline.cling.transport.impl.MulticastReceiverImpl init
INFORMAÇÕES: Joining multicast group: /239.255.255.250:1900 on network interface: Qualcomm Atheros QCA9377 Wireless Network Adapter
abr 21, 2021 1:15:53 AM org.fourthline.cling.transport.impl.MulticastReceiverImpl init
INFORMAÇÕES: Creating wildcard socket (for receiving multicast datagrams) on port: 1900
abr 21, 2021 1:15:53 AM org.fourthline.cling.transport.impl.MulticastReceiverImpl init
INFORMAÇÕES: Joining multicast group: /239.255.255.250:1900 on network interface: VirtualBox Host-Only Ethernet Adapter
abr 21, 2021 1:16:07 AM org.fourthline.cling.transport.impl.StreamServerImpl init
INFORMAÇÕES: Created server (for receiving TCP streams) on: /192.168.0.3:58863
abr 21, 2021 1:16:07 AM org.fourthline.cling.transport.impl.DatagramIOImpl init
INFORMAÇÕES: Creating bound socket (for datagram input/output) on: /192.168.0.3
abr 21, 2021 1:16:07 AM org.fourthline.cling.transport.impl.StreamServerImpl init
INFORMAÇÕES: Created server (for receiving TCP streams) on: /192.168.56.1:58866
abr 21, 2021 1:16:07 AM org.fourthline.cling.transport.impl.DatagramIOImpl init
INFORMAÇÕES: Creating bound socket (for datagram input/output) on: /192.168.56.1
abr 21, 2021 1:16:07 AM org.fourthline.cling.UpnpServiceImpl <init>
INFORMAÇÕES: <<< UPnP service started successfully
abr 21, 2021 1:16:13 AM org.fourthline.cling.protocol.RetrieveRemoteDescriptors describe
ADVERTÊNCIA: Could not hydrate device or its services from descriptor: (RemoteDevice) Identity: (RemoteDeviceIdentity) UDN: uuid:KNKODM2K5000000000000000000000000000075452, Descriptor: http://192.168.0.10:9080, Root: true
abr 21, 2021 1:16:13 AM org.fourthline.cling.protocol.RetrieveRemoteDescriptors describe
ADVERTÊNCIA: Cause was: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; O conteúdo não é permitido no prólogo.
abr 21, 2021 1:16:41 AM org.fourthline.cling.UpnpServiceImpl$1 run
INFORMAÇÕES: >>> Shutting down UPnP service...

Alguma dica? Obrigado.

java – Validate a SSL certificate using apache Http client tool

I’m using java and Apache Http client to access a Public Rest API. I got the Rest API’s URI by just google search. When I looks at the URL, it says https, and the SSL certificate is issued by “Amazon”.

So my question is how to verify the certificate at java code, if possible could you please provide any sample code to validate the certificate?

java – Consulta sobre actualización/modificación de tablas SQLite

Tengo una duda, ¿Cómo puedo una nueva tabla a una BD en SQLite sin tener que borrar/eliminar la misma o desinstalar la App. La consulta radica en que si elimino la BD perdería todos los datos almacenados y eso no sería conveniente. Entonces, ¿Cómo puedo lograrlo sin eliminarla?

Actualmente, esto es lo que tengo en mi BD:

    @Override
    public void onCreate(SQLiteDatabase db){
        db.execSQL(CopaTablaSqlite.TABLA_COPA_SQL);
        db.execSQL(CoronaTablaSqlite.TABLA_CORONA_SQL);
        db.execSQL(FlorTablaSqlite.TABLA_FLOR_SQL);
        db.execSQL(PlumaTablaSqlite.TABLA_PLUMA_SQL);
        db.execSQL(RelojTablaSqlite.TABLA_RELOJ_SQL);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
        db.execSQL(CopaTablaSqlite.TABLA_COPA_SQL);
        db.execSQL(CoronaTablaSqlite.TABLA_CORONA_SQL);
        db.execSQL(FlorTablaSqlite.TABLA_FLOR_SQL);
        db.execSQL(PlumaTablaSqlite.TABLA_PLUMA_SQL);
        db.execSQL(RelojTablaSqlite.TABLA_RELOJ_SQL);
    }

Ahora, si quisiese agregar una nueva tabla:

    @Override
    public void onCreate(SQLiteDatabase db){
        db.execSQL(CopaTablaSqlite.TABLA_COPA_SQL);
        db.execSQL(CoronaTablaSqlite.TABLA_CORONA_SQL);
        db.execSQL(FlorTablaSqlite.TABLA_FLOR_SQL);
        db.execSQL(PlumaTablaSqlite.TABLA_PLUMA_SQL);
        db.execSQL(RelojTablaSqlite.TABLA_RELOJ_SQL);
        //nueva tabla ↓↓↓
        db.execSQL(RelojTablaSqlite.TABLA_NUEVA_SQL);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
        db.execSQL(CopaTablaSqlite.TABLA_COPA_SQL);
        db.execSQL(CoronaTablaSqlite.TABLA_CORONA_SQL);
        db.execSQL(FlorTablaSqlite.TABLA_FLOR_SQL);
        db.execSQL(PlumaTablaSqlite.TABLA_PLUMA_SQL);
        db.execSQL(RelojTablaSqlite.TABLA_RELOJ_SQL);
        //nueva tabla ↓↓↓
        db.execSQL(RelojTablaSqlite.TABLA_NUEVA_SQL);
    }

Esto claramente, genera el error de que no existe la tabla. ¿Cómo puedo solucionarlo? ¿Es posible solucionarlo? Desde ya, muchas gracias.

strings – Censoring emails in Java

I’m working on a simple method that would censor emails (GPDR stuff) so they won’t show the full name of a user, with 1st character, optional dot, 1st character after the dot and whatever is left after the @ to be left uncensored. So, the intent is like this:

Email to be censored: name.lastname@email.com

Desired effect: n***.l*******@email.com

I’ve written this:

public static String getCensoredUsername(String username) {
    if (username.contains("@")) {
        char() chars = username.toCharArray();
        for (int i = 1; i < chars.length; i++) {
            boolean isCurrentCharacterADot = chars(i) == '.';
            boolean isPreviousCharacterADot = chars(i - 1) == '.';

            if (chars(i) == '@') {
                break;
            }
            if (chars(i) == '.') {
                chars(i) = '.';
            } else if (!isCurrentCharacterADot && !isPreviousCharacterADot) {
                chars(i) = '*';
            }
        }
        return String.valueOf(chars);
    }
    return username;
}

It feels to me very Java 6. What would make it look better?

Basic java text-based management game

In a few hours I threw together this little text-based java game. Pretty much you’re managing a forest and have to try and keep it together while keeping enough of a profit to move forward.

package com.company;

import java.util.Arrays;
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;

import static java.lang.Integer.parseInt;

public class Main {

    static int gold = 60, trees = 15, unr_trees = 0, r_trees = 0, fertilizer = 1, animal_protection = 0;

    static int refinesLeftThisTurn;

    static int turn = 1, actionsUsedThisTurn = 0;

    static int wildlifeProtection;

    public static void main(String() args) {
        cls();
        System.out.println("Treemnger:nn");
        game();
    }

    public static void game() {
        boolean endCommand = false;
        Scanner s = new Scanner(System.in);

        while (true) {
            endCommand = false;
            refinesLeftThisTurn = 10;
            actionsUsedThisTurn = 0;
            System.out.println("Turn: " + turn);

            System.out.println("n");
            while (!endCommand) {
                System.out.println("Enter a command (type 'help' for list)");
                String commandEntered = s.nextLine();

                String() splitCommand = commandEntered.split(" ");

                String command = splitCommand(0);
                String() subcommands = Arrays.copyOfRange(splitCommand, 1, commandEntered.length());

                switch (command.toLowerCase()) {
                    case "help":
                        System.out.println("Commands: 'help', 'resources', 'chop', 'sell', 'refine', 'buy', 'use', 'clear', 'end'");
                        endCommand = false;
                        break;

                    case "resources":
                        printResources();
                        endCommand = false;
                        break;

                    case "chop":
                        if (subcommands(0) != null) {
                            if (trees - parseInt(subcommands(0)) >= 0) {
                                trees -= parseInt(subcommands(0));
                                unr_trees += parseInt(subcommands(0));
                                if (rng(1, 30) == 1) {
                                    System.out.println("Lucky! You got 5 extra wood!");
                                    unr_trees += 5;
                                }

                            } else {
                                System.out.println("You need more trees!");
                                break;
                            }
                        } else {
                            System.out.println("Please provide number of trees to be cut, e.g. 'chop 3'.");
                            break;
                        }
                        endCommand = false;
                        actionsUsedThisTurn++;
                        break;

                    case "sell":
                        if (subcommands(0) == null) {
                            System.out.println("Please provide the type of wood to sell!");
                            break;
                        }
                        if (subcommands(1) == null || NotIntString(subcommands(1))) {
                            System.out.println("Please provide the amount of wood to sell!");
                            break;
                        }

                        switch (subcommands(0)) {
                            case "unrefined":
                                if (unr_trees - parseInt(subcommands(1)) >= 0) {
                                    unr_trees -= parseInt(subcommands(1));
                                    gold += rng(4, 6) * parseInt(subcommands(1));

                                } else {
                                    System.out.println("You need more unrefined logs!");
                                }
                                break;
                            case "refined":
                                if (r_trees - parseInt(subcommands(1)) >= 0) {
                                    r_trees -= parseInt(subcommands(1));
                                    gold += rng(13, 17) * parseInt(subcommands(1));
                                } else {
                                    System.out.println("You need more refined logs!");
                                }
                                break;
                            default:
                                System.out.println("Please specify either 'unrefined' or 'refined' logs.");
                                break;
                        }
                        actionsUsedThisTurn++;
                        break;

                    case "refine":
                        if (refinesLeftThisTurn < 0) {
                            System.out.println("You cannot refine any more times this turn! Wait till next turn to regain your 10 refines!");
                        }
                        if (subcommands(0) == null) {
                            System.out.println("Please provide the amount of wood to refine!");
                            break;
                        }

                        if (unr_trees - parseInt(subcommands(0)) >= 0 || gold - (parseInt(subcommands(0)) * 5) >= 0) {
                            unr_trees -= parseInt(subcommands(0));
                            r_trees += parseInt(subcommands(0));
                            gold -= parseInt(subcommands(0)) * 5;
                            refinesLeftThisTurn -= parseInt(subcommands(0));
                        }
                        actionsUsedThisTurn++;
                        break;

                    case "buy":
                        if (subcommands(0) == null) {
                            System.out.println("Please provide what you would like to buy!");
                            break;
                        }
                        if (subcommands(1) == null || NotIntString(subcommands(1))) {
                            System.out.println("Please provide the amount you would like to buy!");
                            break;
                        }

                        switch (subcommands(0)) {
                            case "fertilizer":
                                if ((gold - parseInt(subcommands(1))) * 50 >= 0) {
                                    fertilizer += parseInt(subcommands(1));
                                    gold -= parseInt(subcommands(1)) * 50;
                                    if (rng(1, 20) == 1) {
                                        System.out.println("Lucky! You got 2 extra fertilizer!");
                                        fertilizer += 2;
                                    }
                                }
                                break;
                            case "wildlifeprotection":
                                if ((gold - parseInt(subcommands(1))) * 50 >= 0) {
                                    animal_protection += parseInt(subcommands(1));
                                    gold -= parseInt(subcommands(1)) * 40;
                                    break;
                                }

                            default:
                                System.out.println("Please specify either 'fertilizer' or 'wildlifeprotection'");
                                break;
                        }
                        actionsUsedThisTurn++;
                        break;

                    case "use":
                        if (subcommands(0) == null) {
                            System.out.println("Please provide what you would like to use!");
                            break;
                        }
                        if (subcommands(1) == null || NotIntString(subcommands(1))) {
                            System.out.println("Please provide how many of that item you would like to use!");
                            break;
                        }

                        switch (subcommands(0)) {
                            case "fertilizer":
                                if (fertilizer - parseInt(subcommands(1)) >= 0) {
                                    fertilizer -= parseInt(subcommands(1));
                                    trees += rng(2, 4);
                                    if (rng(1, 10) == 1) {
                                        System.out.println("Lucky you! You get 5 extra trees!");
                                        trees += 5;
                                    }
                                } else {
                                    System.out.println("You need more fertilizer!");
                                }
                                break;
                            case "wildlifeprotection":
                                if (animal_protection - parseInt(subcommands(1)) >= 0) {
                                    animal_protection -= parseInt(subcommands(1));
                                    wildlifeProtection++;
                                } else {
                                    System.out.println("You need more wildlife protection!");
                                }
                                break;
                            default:
                                System.out.println("Please specify either 'fertilizer' or 'wildlifeprotection'");
                        }
                        actionsUsedThisTurn++;
                        break;

                    case "clear":
                        cls();
                        break;

                    case "end":
                        cls();
                        System.out.println("Thank's for playing!");
                        System.exit(0);

                    default:
                        System.out.println("Invalid command!");
                        break;
                }

                if (actionsUsedThisTurn >= 5) {
                    turn++;
                    endCommand = true;
                }
            }
            if (wildlifeProtection == 0) {
                trees -= rng(2, 4);
            }
            if (trees < 0) {
                cls();
                System.out.println("You lost, making it to " + turn + " turns! Make it longer next time!");
                System.exit(0);
            }
        }
    }

    public static void cls() {
        System.out.print("33(H33(2J");
        System.out.flush();
    }

    public static void printResources() {
        String s = "Trees: " +
                trees +
                "nGold: " +
                gold +
                "nnUnrefined Trees: " +
                unr_trees +
                "nRefined Trees: " +
                r_trees +
                "nnFertilizer: " +
                fertilizer +
                "nAnimal Protection: " +
                animal_protection;
        System.out.println(s);
    }

    private static boolean NotIntString(String string) {
        try {
            parseInt(string);
            return false;
        } catch (NumberFormatException e) {
            return true;
        }
    }

    private static int rng(int min, int max) {
        return ThreadLocalRandom.current().nextInt(min, max + 1);
    }
}

GitHub

java – JPQL Query Syntax Help: Trying to get count for a query and count for a subquery that has one more condition

@Query(value = "Select NEW com.xx.domain.MaxTestsStats(rep.component.componentName, count(run), count(run) where run.testStatus = 'SKIPPED') " +
        "from TestRun run " +
        "join run.testReport rep " +
        "where (:environment IS NULL OR rep.environmentAlias = :environment) " +
        "and (:type IS NULL OR rep.testType = :type) " +
        "and (cast(:from as date) IS NULL OR rep.testStartTime >= :from) " +
        "and (cast(:to as date) IS NULL OR rep.testStartTime <= :to) " +
        "group by (rep.component.componentName) "
        )
fun findMaxTestsStats(@Param("environment") environment: String?, @Param("from") from: Date?, @Param("to") to: Date?, @Param("type") type:TestType?): List<MaxTestsStats>

The code above will not work because of: “count(run) where run.testStatus = ‘SKIPPED'” but I hope the intent of what I’m trying to do is clear.

I want to return a value with the component name, the count of all test runs, and the count of all test runs where run.testStatus is ‘SKIPPED’. How do I restructure this query to return both counts? The second count should just be a subset of the first count.


Relevant Entity list:

@Entity

@Table(name = “test_runs”)

data class TestRun(

    @Id
    @GeneratedValue
    val id: UUID? = null,

    @ManyToOne(fetch = FetchType.LAZY)
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    val testReport: TestReport,

    val testName: String,

    @Enumerated(EnumType.STRING)
    val testStatus: TestStatus,

    val testException: String? = null,

    val duration: Long

)

@Entity

@Table(name = “test_reports”)

data class TestReport(

    @Id
    @GeneratedValue
    val id: UUID? = null,

    @OneToOne
    val component: Component,

    val environmentAlias: String,

    @Enumerated(EnumType.STRING)
    val testType: TestType,

    @Enumerated(EnumType.STRING)
    var status: TestStatus?,

    var testStartTime: Timestamp?,

    var testStopTime: Timestamp?,

    @OneToMany(fetch = FetchType.LAZY, cascade = (CascadeType.ALL), mappedBy = "testReport")
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    var testRuns: MutableList<TestRun>,

    @OneToOne(fetch = FetchType.LAZY, cascade = (CascadeType.ALL), mappedBy = "testReport")
    var testReportCoverage: TestReportCoverage? = null

)

@Entity
data class MaxTestsStats(

    @Id
    var component: String,
    var total: Long,
    var ignored: Long

)

java 8 – ¿Como crear componentes para un JFrame?

Intento crear componentes, en java como los botones o labels, de tal manera que cada uno sea independiente y pueda actualizarse independientemente del otro. Intente algo asi:

public class Bit extends Component{
        @Override
public void paint(Graphics g){
  g.setColor(asignarColor());

  g.fillOval(x, y, 20, 20);
    
  if(mostrarCarga){g.drawString(label, x + 23, y + 5);}
   
}

pero al probarlo solo se agrega el ultimo que agregue

public static void main(String() args) throws InterruptedException {
    JFrame frame = new JFrame("Prueba de Animación");
            
    //Linea  m = new Linea(50,50,700,100,true);
    
            //Linea  m2 = new Linea(150,200,500,800,true);
            
            Bit a = new Bit(true, 50, 60);
            a.setVisible(true);
            frame.add(a);
            Bit b = new Bit(false, 100, 60);
            b.setVisible(true);
            frame.add(b);
            Bit c = new Bit(true, 150, 200);
            c.setVisible(true);
            frame.add(c);
         }

en este caso el unico que se agregaria seria el Bit c

(Obvie el constructor del Bit)

java – Counting the number of unique IP addresses in a very large file. Follow-Up #1

It’s a follow-up question.
A previous version
of this code has been posted on Code Review about 2 weeks ago.

What was done after the last review

In fact, the entire application is rewritten from scratch. Here
is current version with tests and JavaDoc.

I tried to split the application into small classes that have only one responsibility and can be re-used and extended.

The main approach to solve a problem has not changed. I still put one value in accordance with each ip and set a bit with the corresponding index in the bit array. The required amount of memory remained the same about 550-600 MB. The speed has increased, now I am practically limited to the performance of my hard disk. It is still assumed that only valid IPs will be in the file.

I deleted all JavaDoc comments from code examples, because they occupy more space than the code itself.

FixedSizeBitVector

I wrote a simple implementation of the bit array that allows you to store N bits with indexes from 0 to N-1. There are
three operations are supported: set bit, examine bit’s value, and get the number of all the set bits.
getCapacity() method used for testing and may be useful in other cases.

I do not bring the BitVector interface due to its primitiveness and simplicity.

package chptr.one;

public class FixedSizeBitVector implements BitVector {

    public static final long MIN_CAPACITY = 1L;
    public static final long MAX_CAPACITY = 1L << 32;

    private final long capacity;
    private final int() intArray;
    private long cardinality;

    public FixedSizeBitVector(long capacity) {
        if (capacity < MIN_CAPACITY || capacity > MAX_CAPACITY) {
            throw new IllegalArgumentException("Capacity must be in range (1.." + MAX_CAPACITY + ").");
        }
        int arraySize = 1 + (int) ((capacity - 1) >> 5);
        this.intArray = new int(arraySize);
        this.capacity = capacity;
    }

    private void checkBounds(long bitIndex) {
        if (bitIndex < 0 || bitIndex >= capacity) {
            throw new IllegalArgumentException("Bit index must be in range (0.." + (capacity - 1) + ").");
        }
    }

    @Override
    public void setBit(long bitIndex) {
        checkBounds(bitIndex);
        int index = (int) (bitIndex >> 5);
        int bit = 1 << (bitIndex & 31);
        if ((intArray(index) & bit) == 0) {
            cardinality++;
            intArray(index) |= bit;
        }
    }

    @Override
    public boolean getBit(long bitIndex) {
        checkBounds(bitIndex);
        int index = (int) (bitIndex >> 5);
        int bit = 1 << (bitIndex & 31);
        return (intArray(index) & bit) != 0;
    }

    @Override
    public long getCapacity() {
        return capacity;
    }

    @Override
    public long getCardinality() {
        return cardinality;
    }
}

UniqueStringCounter

This class implements the counter of unique lines in the input Iterable<String> sequence. The counter uses BitVector
implementation. To work, it is required that the input sequence has a final number of possible string-values and this
amount did not exceed the maximum capacity of the bit vector used.

It also requires a hash function that puts a String and a long in an unambiguous match.

package chptr.one;

import javax.validation.constraints.NotNull;
import java.util.Objects;
import java.util.function.ToLongFunction;

public class UniqueStringCounter {

    private final Iterable<String> lines;
    private final ToLongFunction<String> hashFunction;
    private final BitVector bitVector;
    private long linesProcessed;

    public UniqueStringCounter(@NotNull Iterable<String> lines,
                               long capacity,
                               @NotNull ToLongFunction<String> hashFunction) {

        Objects.requireNonNull(lines);
        Objects.requireNonNull(hashFunction);
        this.lines = lines;
        this.hashFunction = hashFunction;
        this.bitVector = new FixedSizeBitVector(capacity);
    }

    public long count() {
        for (String line : lines) {
            long value = hashFunction.applyAsLong(line);
            bitVector.setBit(value);
            linesProcessed++;
        }
        return bitVector.getCardinality();
    }

    public long getLinesProcessed() {
        return linesProcessed;
    }
}

IpStringHashFunction

Hash function to convert a String to a long value. This function must generate a unique value for each unique line,
the collisions are not allowed.

I tested several options for the conversion of IP-String in the long-value and came to the conclusion that they all work around at the same speed that the InetAddress. I do not see the reasons to write my own implementation when the speed of the library function is completely satisfied.

The processing of exceptions really is not needed here, because according to the terms of the task, I am guaranteed that there will be only valid IP. I had to make this processing since otherwise I can’t use this function as a parameter for UniqueStringCounter.

package chptr.one;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.function.ToLongFunction;

public class IpStringHashFunction implements ToLongFunction<String> {

    @Override
    public long applyAsLong(String value) {
        long result = 0;
        try {
            for (byte b : InetAddress.getByName(value).getAddress())
                result = (result << 8) | (b & 255);
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
        return result;
    }
}

BufferedReaderIterable

A simple adapter that allows you to work with BufferedReader as with Iterable. I could not come up with a better way
to send the contents of the file in UniqueStringCounter, which expects to the Iterable<String> as parameter.

package chptr.one;

import javax.validation.constraints.NotNull;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.Objects;

public class BufferedReaderIterable implements Iterable<String> {

    private final Iterator<String> iterator;

    public BufferedReaderIterable(@NotNull BufferedReader bufferedReader) {
        Objects.requireNonNull(bufferedReader);
        iterator = new BufferedReaderIterator(bufferedReader);
    }

    public Iterator<String> iterator() {
        return iterator;
    }

    private static class BufferedReaderIterator implements Iterator<String> {

        private final BufferedReader bufferedReader;

        private BufferedReaderIterator(BufferedReader bufferedReader) {
            this.bufferedReader = bufferedReader;
        }

        @Override
        public boolean hasNext() {
            try {
                return bufferedReader.ready();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public String next() {
            String line;
            try {
                line = bufferedReader.readLine();
                if (line == null) {
                    try {
                        bufferedReader.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return line;
        }
    }
}

IpCounterApp

The main class of the application. Accepts the file name in the -file parameter.

package chptr.one;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;

public class IpCounterApp {

    private static String parseFileName(String() args) {
        Objects.requireNonNull(args, "No arguments found. Use -file file-name to processing file.");
        if (args.length == 2 || "-file".equals(args(0))) {
            return args(1);
        }
        return null;
    }

    public static void main(String() args) {
        String fileName = parseFileName(args);
        if (fileName == null) {
            System.err.println("Wrong arguments. Use -file file-name to processing file.");
            return;
        }

        Path filePath = Paths.get(fileName);
        if (!Files.exists(filePath)) {
            System.err.printf("File %s does not exists.n", filePath);
            return;
        }

        try {
            System.out.printf("Processing file: %sn", filePath);
            long startTime = System.nanoTime();
            BufferedReader bufferedReader = Files.newBufferedReader(filePath);
            Iterable<String> strings = new BufferedReaderIterable(bufferedReader);
            UniqueStringCounter counter = new UniqueStringCounter(strings, 1L << 32, new IpStringHashFunction());
            long numberOfUniqueIp = counter.count();
            long linesProcessed = counter.getLinesProcessed();
            long elapsedTime = System.nanoTime() - startTime;
            System.out.printf("Unique IP addresses: %d in total %d.n", numberOfUniqueIp, linesProcessed);
            System.out.printf("Total time: %d milliseconds.n", elapsedTime / 1_000_000);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Why do I ask the new Review?

In previous question
I received a few excellent answers and one excellent bug report. I tried to take into account so many comments as I
could. I also tried to reconsider my approach to the design of classes. I am interested in mostly three questions:

  • How are my new classes are suitable for re-use and extension? What other abstractions can be allocated here and should
    it be done?
  • What should I do with error processing? I know that now it is bad. I just try to fall as early as possible.
  • And most importantly. Do I move in the right direction? I am a newbie in programming and get an overview for my code is
    the only way to learn how to write a quality and understandable code.