0% acharam este documento útil (0 voto)
2 visualizações20 páginas

Java

O documento aborda conceitos fundamentais de Java, incluindo tipos primitivos e não primitivos, estruturas de controle como if-else e switch-case, além de arrays e loops. Também explora programação orientada a objetos, incluindo herança, interfaces e classes abstratas, com exemplos práticos relacionados ao universo de Naruto. O conteúdo é voltado para iniciantes e intermediários que desejam entender a linguagem Java através de exemplos lúdicos.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
2 visualizações20 páginas

Java

O documento aborda conceitos fundamentais de Java, incluindo tipos primitivos e não primitivos, estruturas de controle como if-else e switch-case, além de arrays e loops. Também explora programação orientada a objetos, incluindo herança, interfaces e classes abstratas, com exemplos práticos relacionados ao universo de Naruto. O conteúdo é voltado para iniciantes e intermediários que desejam entender a linguagem Java através de exemplos lúdicos.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

Java

Tipos primitivos
tipo primitivo não recebe metodos* dados primitivos - int, float, double, float, char, boolean,
short objetivo da aula - Criar um Ninja naruto

String nameNinja = "Naruto"; // string é um dado não primitivo


int age = 16; // int tem valor limitado
char initial = 'N';
double height = 1.64;
boolean aliveOrDead = true;
Long bankBalance = 22222222456L; // Long comporta números muito altos

ShortCuts
ShortCuts
(psvm -> public static void main)
(sout -> [Link]())
(alt insert -> para criar um construtor automaticamente)

Dados não primitivos


DADOS NÃO PRIMITIVOS: String, Array, Class, enum
objetivo: criar um ninja e atribuir metodos a ele
// DA PARA ACESSAR METODOS EM DADOS NÃO PRIMITIVOS

String nome = "Naruto Uzumaki";


String nomeMaiusculo = [Link](); // vai colocar tudo em MAIUSCULO

[Link]("Esse nome esta em UpperCase: " + nomeMaiusculo);


[Link]("Esse nome esta normal: " + nome);

String aldeia = "Aldeia da Folha";


String aldeiaEmCaixaBaixa = [Link](); // deixa em minusculo

[Link](aldeiaEmCaixaBaixa);

String nome2 = " Sasuke Uchiha ";


String modificandoNome2 = [Link](); // o strip funciona igual o
strip do python
[Link](modificandoNome2);
int idade = 21;
String aldeia2 = "Aldeia da folha";
String renegado = [Link]("Aldeia", "Renegado"); // mesma coisa
com o replace funciona, (valor que vc quer mudar, novo valor)
[Link](renegado);
String nome3 = "Kakashi";
int tamanhoNome = [Link](); // aqui pega o tamanho da string

[Link](tamanhoNome);

String nome4 = "Sakura Haruno";

// [Link](); equals serve para comparar uma string com outra, equalsIgnoreCase
serve para ignorar a Caixa alta ou baixa
// String testeSplit = [Link](String);

Condicinionais
IF E ELSE

// if (condicao) {
// Faça isso
// } else {
// Faça isso
// }

// if (condicao) {
// Faça isso
// } else if (condicao) {
// ou faça isso
// } else {
// senão Faça isso
// }

SWITCH CASE

SwitchCase: Que servem para gerar casos especificos

switch (ninja) {
case 1:
[Link]("Vc escolheu Naruto, Rasengaan!!");
break;
case 2:
[Link]("Vc escolheu Sasuke, Chidorii!!");
break;
case 3:
[Link]("Vc escolheu a Sakura, Janaraaa!!");
break;
case 4:
[Link]("Vc escolheu Kakashi ninja copiador!!");
break;
default:
[Link]("Escolha entre 1 ate 4");
break;

OPERADOR TERNARIO

variavel = (condicao) ? verdadeiro : falso;

mensagem = (statusCode == 200) ? "Ok" : "Erro";

Arrays
// fazendo array com strings
// new String[3] serve para criar quanto de memoria

String[] ninjas = new String[3];


ninjas[0] = "Naruto Uzumaki";
ninjas[1] = "Sasuke Uchiha";
ninjas[2] = "Sakura Haruno";

[Link](ninjas[0]);
[Link](ninjas[1]);
[Link](ninjas[2]);

// para adicionar mais nomes tem que disponibilizar mais espaço no array

ninjas = new String[4];


ninjas[3] = "Hinata Hyuuga";
[Link](ninjas[3]);

// para adicionar mais nomes tem que disponibilizar mais espaço no array
ninjas = new String[4];
ninjas[3] = "Hinata Hyuuga";
[Link](ninjas[3]);
// se printar o array sem um ele tiver um objeto na memoria (algo no indice especifico) se for
int vai ser 0, String vai ser null, boolean vai ser false, double vai ser 0.0 e etc
// redeclarar
ninjas[0] = "Boruto Uzumaki";
[Link](ninjas[0]);

// REDECLARAR O ARRAY <- VAI SUBSTITUIR TODOS OS DADOS ANTERIORES


[Link]("-- HOKAGES --");
ninjas = new String[7];
ninjas[0] = "Hashirama Senju";
ninjas[1] = "Tobirama Senju";
ninjas[2] = "Hiruzen Sarutobi";
ninjas[3] = "Minato Namikaze";
ninjas[4] = "Tsunade Senju";
ninjas[5] = "Kakashi Hatake";
ninjas[6] = "Naruto Uzumaki";

for (String n : ninjas) {


[Link](n);
}

ARRAYS MULTIDIMENSIONAIS

String[][] ninjasEAldeias = new String[3][3];

ninjasEAldeias[0][0] = "Konoha";
ninjasEAldeias[0][1] = "Naruto";
ninjasEAldeias[0][2] = "Uzumaki";
ninjasEAldeias[1][0] = "Sasuke";
ninjasEAldeias[1][1] = "Uchiha";
ninjasEAldeias[1][2] = "Renegado";
ninjasEAldeias[2][0] = "Sakura";
ninjasEAldeias[2][1] = "Haruno";
ninjasEAldeias[2][2] = "Konoha";

// [Link](ninjasEAldeias[0][1]);
// [Link](ninjasEAldeias[0][2]);
// [Link](ninjasEAldeias[0][0]);
// em arrays 2D ou multidimensionais vc usa for each duplo para imprimir for (String[] p :
ninjasEAldeias) {
for (String n : p) {
[Link](n);
}
[Link](); // <- quebra de linha
}

LOOPS
WHILE

// while (condição) { //enquanto


// //bloco de código
// }

int numeroClones = 0;
int numeroMaximoDeClones = 40;

// while (numeroClones <= numeroMaximoDeClones) {


// [Link]("O Naruto fez um clone! " + numeroClones);
// numeroClones++;
// }

FOR

// for (inicialização; condição; incremento) {


// //bloco de código
// }

for (int i = 0; i <= numeroMaximoDeClones; i++) {


[Link]("O Naruto fez um clone! " + i);
}

FOR EACH

// for each (tipo variável : coleção/array) {


// //bloco de código
// }
// serve para percorrer arrays e coleções
String[] ninjas = {"Naruto", "Sasuke", "Sakura", "Kakashi"};
for (String ninja : ninjas) {
[Link]("Ninja: " + ninja);
}

PROGRAMAÇÃO ORIENTADA A OBJETOS


Ninja Naruto = new Ninja(); // Naruto é o objeto, Ninja é a classe base
Uzumaki Naruto = new Uzumaki(); // Naruto é o objeto, Uzumaki é a classe filha da classe
Ninja.

[Link] = "Naruto Uzumaki";


[Link] = 18;
[Link] = "Aldeia da Folha";
[Link]();

package java10x.nivel_intermediario;

// EXTENDS É PARA FAZER A HERANÇA ENTRE NINJA E UZUMAKI

public class Uzumaki extends Ninja {

public void ModoSabioAtivado() {


[Link]("Meu nome é " + nome + " Ativei o modo sabio!");
}

package java10x.nivel_intermediario;
// molde classe // classe PAI
public class Ninja {
String nome;
String aldeia;
int idade;

// o metodo void não retorna valor nenhum!


// criando um metodo publico personalizado// public void
SharinganAtivado() {

// [Link]("O Sharingan de " + nome + " ativou!");


// }

// metodo String vai ter que retornar uma String obrigatoriamente!


public String EuSouUmNinja() {
return "Oi eu sou um ninja!";
}

// metodo int vai ter que retornar um int obrigatoriamente!

public int anosParaSeTornarHogake(int idadeMinima) {


return idadeMinima - idade;
}

INTERFACE

package java10x.nivel_intermediario.ex05;
public interface Funcionario {
void calcularSalario();
}

package java10x.nivel_intermediario.ex05;
OVERRRIDE É PARA POLIMORFISMO PARA A CLASSE FILHA HERDAR O METODO DA
CLASSE PAI E TER SUAS PROPRIAS CARACTERISTICAS
public class FuncionarioCLT implements Funcionario{
@Override
public void calcularSalario() {
[Link]("Salario de CLT é por final do mês");
}
}

ARRAYLIST BASICO
List funcionarios = new ArrayList<>();

Funcionario pj = new FuncionarioPJ();


[Link]();

Funcionario clt = new FuncionarioCLT();


[Link]();

[Link](new FuncionarioPJ());
[Link](new FuncionarioCLT());

for (Funcionario f : funcionarios) {


[Link]();
}
}

CLASSES ABSTRATAS
package java10x.nivel_intermediario.construtores;
// ABSTRACT PARA DEIXAR A CLASSE ABSTRATA
public abstract class Hokages {
// SHORT CUT PARA CRIAR UM CONSSTRUTOR COM MUITOS DADOS: (alt insert) e
depois selecione as variaveis seleciona a ordem das variaveis
String nome;
int idade;
boolean vivoOuNao;
double altura;
String aldeia;
String principalPoder;

// inicializar um construtor tipo o __init__ em python!( TEM QUE SER O MESMO


NOME DA CLASSE )
// all args constructor
// metodo abstrato public abstract void sabedoriaHogake();

public Hokages(String nome, int idade, boolean vivoOuNao, double altura,


String aldeia, String principalPoder) {
[Link] = nome;
[Link] = idade;
[Link] = vivoOuNao;
[Link] = altura;
[Link] = aldeia;
[Link] = principalPoder;
}
// No args constructor
public Hokages () {

}
public void mostrarInformacoes() {
[Link]("Nome: " + nome);
[Link]("Idade: " + idade);
[Link]((vivoOuNao) ? "Vivo" : "Morto");
}

SENJU HERDA HOKAGES POR CONTA DA CLASSE HOKAGES SER UM MOLDE E SER
ABSTRATA

package java10x.nivel_intermediario.construtores;

public class Senju extends Hokages{


@Override
public void sabedoriaHogake() {
[Link]("Sabedoria do Hashirama");
}

public Senju(String nome, int idade, boolean vivoOuNao, double altura,


String aldeia, String principalPoder) {
super(nome, idade, vivoOuNao, altura, aldeia, principalPoder);
}
}

package java10x.nivel_intermediario.construtores;

public class Main {


public static void main(String[] args) {
Senju Hashirama = new Senju("Hashirama Senju", 55, false, 1.90, "folha", "Madeira");

// da erro porque Hokages é uma classe abstrata então Senju herdou


hokages e seus metodos e construtores então senju que deve ser utilizado

// Hokages hashirama = new Hokages("Hashirama Senju", 55, false, 1.90, "folha",


"Madeira");
// [Link]();

// da erro porque Hokages é uma classe abstrata, então minato tinha que
herdar a classe hokages para dar certo// Hokages minato = new
Hokages("Minato Namikaze", 35, false, 1.80, "Folha", "Teleporte");

// [Link]();

// 1 classe abstrata n pode ser criado objeto


[Link]();
}

DIFERENÇA ENTRE CLASSE ABSTRATA E INTERFACE

Na interface se vc precisar criar variaveis vc tem que settar ela se não da erro tem que
automaticamente atribuir um valor

package java10x.nivel_intermediario.classeabstrataxinterface;

public interface NinjaInterface {


// TEM QUE SETTAR O VALOR AGORA DIFERENTE DA CLASSE ABSTRATA
int idade = 21;
String nome = "Naruto";

// utilize mais metodos em INTERFACE


// ele é obrigatoriamente abstrato public void tacarShuriken();
ja a classe abstrata vc é obrigatoriamente utilizar todos os metodos e as variaveis podem
ser flexiveis e settar os valores depois

package java10x.nivel_intermediario.classeabstrataxinterface;

public abstract class Ninja {


String nome;
String aldeia;
int idade;
// metodos abstratos
public abstract void nomeNinja();

public void TacarKunai() {


[Link]("Meu nome é " + nome + " E taquei kunai");
}

// COM AS CLASSES ABSTRATAS EU ESTOU OBRIGANDO TODO MUNDO QUE VAI


TRABALHAR NO MEU CODIGO A CONSTRUTIR OS OBJETOS COM AS SUBCLASSES

/----------------------------------

Super classes e SubClasses

Superclasses que possuem construtores as subclasses obrigatoriamente vai ter que herdar
esse construtor

um subclasse so pode ter uma superclasse um filho so pode ter uma mãe

HERANÇA MULTIPLA

CRIANDO O KAKASHI QUE POSSUI CARACTERISTICAS UCHIHA E HATAKE E FAZIA


PARTE DA ANBU

package java10x.nivel_intermediario.herancaMultipla;

import java10x.nivel_intermediario.[Link];

public class Main3 {


// juntar interface com classe abstrata para fazer herança multipla pq no java não é possivel
juntar 2 super classes em uma subclasse
public static void main(String[] args) {

Hatake kakashi = new Hatake();


[Link] = "Kakashi";
[Link]();

Uchiha3 sasuke = new Uchiha3();

[Link]();

package java10x.nivel_intermediario.herancaMultipla;

public class Ninja3 {


String nome;
String aldeia;
int idade;

public void mostrarInformacoes() {


[Link]("Nome: " + nome);
[Link]("Aldeia: " + aldeia);
[Link]("Idade: " + idade);
}

package java10x.nivel_intermediario.herancaMultipla;

public class Uchiha3 extends Ninja3 implements sharinganInterface {


@Override
public void sharinganAtivado() {
[Link]("Ativar sharingan uchihas");
}
}

package java10x.nivel_intermediario.herancaMultipla;

public interface sharinganInterface {


void sharinganAtivado();
}

package java10x.nivel_intermediario.herancaMultipla;

public interface Anbu {


void bemvindoAAnbu();
}

package java10x.nivel_intermediario.herancaMultipla;

import [Link];

public class Hatake extends Ninja3 implements sharinganInterface, Anbu { // PODE SE


UTILIZAR VARIAS INTERFACES EM UMA MESMA CLASSE! apenas colcoar a virgula

public void boasVindas() {


[Link]("Eu sou um hatake");
}

@Override
public void sharinganAtivado() {
[Link]("Kakashi Ativou o sharingan");
}

@Override
public void bemvindoAAnbu() {
[Link]("Bem vindo kakasi hatake a Anbu");
}

PODE SE OBSERVAR QUE NO IMPLEMENTS POSSUI 2 INTERFACES, E PODE


COLOCAR VARIAS APENAS DEVE COLOCAR A VIRGULA, MAS ISSO FUNCIONA
APENAS PARA INTERFACES E NÃO PARA CLASSES!

QUANDO INICIALIZA UM CONSTRUTOR ELE SE TORNA IMUTAVEL., ENTÃO VC NÃO


DEVE MEXE-LO E SIM CRIAR UM NOVO COM SOBRECARGA E NOVOS
PARAMETROS.

SOBRECARGA DE METODOS, FUNCIONA ASSIM, VC CRIA UM METODO E SE VC


QUISER CRIAR UM NOVO METODO COM O MESMO NOME VC PODE FAZER UMA
SOBRECARGA COM NOVOS PARAMETROS NESSE NOVO METODO.

// SOBRECARGA DE METODOS OVERLOAD


void inteligenciaDeCombate();

// mudança do overload so que com parametro


void inteligenciaDeCombate(int qi);
isso vale para os construtores tambem mas tem uma
maneira diferente. Utilizase o this()
METODO ToString referencia na memoria, é sempre indicado cada classe ter um metodo
toString para verificar a refencia na memoria

// REFERENCIA DE MEMORIA TO STRING --


@Override
public String toString() {
return "Esse é o metodo to string para refencia de memoria";
}

@Override
public String toString() {
return [Link]();
}

CLASSE FINAL NÃO PODE SER EXTENDIDA MAS PODE CRIAR OBJETOS A PARTIR
DELA DIFERENTE DA CLASSE ABSTRATA QUE NÃO PODE CRIAR OBJETOS
DIRETAMENTE COM ELA MAS PODE SER EXTENDIDA PARA UMA CLASSE FILHA E
ESSA CLASSE FILHA HERDAR OS METODOS DA CLASSE ABSTRATA!

package java10x.nivel_intermediario.classeabstrataxinterface;
// uma classe final é uma classe que não pode ser extendida
// nenhuma classe pode herdar essa
// mas é possivel criar um objeto dela diferente das classes abstratas
final public class Anbu {
String nome;

public void anbu() {


[Link]("Eu sou um anbu!");

Anbu ninjaAnbu = new Anbu();


[Link] = "Kakashi";
ENCAPSULAMENTO

PRIVATE -> DEIXAR PRIVADO


PUBLIC -> DEIXA PUBLICO
PROTECTED -> DEIXA SEMI PRIVADO

GET -> PUXA O VALOR


SET -> SETA O VALOR ou DEFINE O VALOR

package java10x.nivel_intermediario.encapsulamento;

public class carro {


String nome; // <- deixa o atributo em public automaticamente
private String dono; // <- deixa o atributo totalmente privado sem permissão para entrar
protected double preco; // <- deixa o atributo semi protejido mas pode entrar

// tirar dados ou mostrar para o usuario use o GET public String


getNome() {
return nome;
}
// Setter recebe valores ele seta valores
public void setNome(String novoNome) {
nome = novoNome;
}

public double getPreco() {


return preco;
}

public void setDono(String novoDono) {


[Link] = novoDono;
}

public String getDono() {


return dono;
}

public void setPreco(double preco) {


[Link] = preco;
}

ARRAYLIST

List ninjass = new ArrayList<>();


// add serve para adicionar
[Link]("Naruto");
[Link]("Sasuke");
[Link]("Sakura");
[Link]("Kakashi");
[Link]("NinjasList = " + ninjass);

// remove serve para remover o nome


[Link]("Kakashi");
[Link]("NinjasList = " + ninjass);

// trocar elementos
[Link](2, "Hashirama"); // set passa o index e o que quer trocar

[Link]("NinjasList = " + ninjass);

// List numeros = new ArrayList();

// ver o tamanho da lista


int tamanho = [Link]();
[Link](tamanho);
[Link]([Link]());

ARQUITETURA EM CAMADAS

Model (ou Entity): É o molde. Representa a tabela do banco de dados em forma de


classe Java. É onde você define os campos (id, nome, email).
Repository: É o porteiro do banco. É uma interface que contém os métodos de busca
e salvamento (save, findById). No Spring Data JPA, ele já te entrega o SQL pronto.
DAO (Data Access Object): É o jeito antigo/específico do Repository. Enquanto o
Repository é mais abstrato, o DAO é usado quando você precisa escrever consultas
SQL complexas ou lógicas de acesso a dados muito manuais.
Service: É o cérebro. Onde a lógica de negócio acontece. Ele chama o Repository para
buscar dados, faz cálculos ou validações, e decide o que deve ser feito.
App (ou Application): É o ponto de partida. Geralmente é a classe que contém o
método main e as configurações globais que sobem todo o ecossistema do Spring.

exemplo

1. Model (A Entidade)
Representa os dados.
Java
@Entity
public class Usuario {
@Id
private Long id;
private String nome;
private String email;
// Getters e Setters
}

### 2. Repository (A Interface)

Acesso ao banco sem precisar escrever SQL (Spring Data JPA).

public interface UsuarioRepository extends JpaRepository<Usuario, Long> {


// O Spring cria o "SELECT * FROM usuario WHERE email = ..."
automaticamente
Optional<Usuario> findByEmail(String email);
}

### 3. DAO (Acesso Específico)

Usado para consultas customizadas ou manuais (JDBC/EntityManager).

Java

@Repository
public class UsuarioDAO {
@PersistenceContext
private EntityManager em;

public List<Usuario> buscarUsuariosComFiltroComplexo() {


return [Link]("SELECT u FROM Usuario u WHERE ...",
[Link]).getResultList();
}

4. Service (A Lógica)
Onde as regras de negócio "moram".

Java
@Service
public class UsuarioService {
@Autowired
private UsuarioRepository repository;

public Usuario salvarUsuario(Usuario usuario) {


if ([Link]([Link]()).isPresent()) {
throw new RuntimeException("Email já cadastrado!");
}
return [Link](usuario);
}
}

### 5. App (A Inicialização)

O ponto de entrada do Spring Boot.

Java

@SpringBootApplication
public class SistemaApplication {
public static void main(String[] args) {
[Link]([Link], args);
}
}

----------------------------------------------------------------------------
-----------------------------

ESTRUTURA DE DADOS, PILHA, FILA, LISTAS ENCADEADS(LINKED LIST)

// Array
String[] ninjasArray = new String[3];

// lista
List<String> ninjasList = new ArrayList<>();

// Stack pilha
Stack<String> ninjasStack = new Stack<>();

[Link]("Naruto uzumaki");
[Link]("Minha Stack atual = " + ninjasStack);
// push() adicionar elemento na pilha
[Link]("Sasuke Uchiha");
[Link]("Sakura Haruno");
[Link]("Minha Stack atual = " + ninjasStack);
// pop() tirar o elemento da pilha, tira o elemento que esta no topo
[Link]();
[Link]("Minha stack atualizada com pop " + ninjasStack);
// peek() verificar o proximo elemento da pilha
[Link]("Minha stack com o proximo elemento do topo " +
[Link]());
// size() verificar o tamanho da quantidade de elementos da pilha
[Link]("Tamanho da stack: " + [Link]());

// ------------------------

// Qeues = Fila
Queue<String> ninjasFila = new LinkedList<>(); // <-- a fila é inicializada
assim porque ela faz parte da familia lista encadeada
[Link]("Naruto");
[Link]("Sasuke");
[Link]("Sakura");
[Link]("Kakashi");
[Link]("Shikamaru");

// Mostrar a fila
[Link]("Ninjas na fila: " + ninjasFila);

// Tirar um ninja da fila


[Link](); // vai atender o primeiro indice da fila e vai remover!

[Link]("Ninjas na fila depois do poll: " + ninjasFila);

// Como ver quem é o primeiro da fila


[Link]("Ver o primeiro da fila: " + [Link]());

[Link]("Hashirama");
[Link]("Tobirama");

[Link]("Ninjas na fila: " + ninjasFila);

// não da Deletar o ultimo


// não da para remover porque é uma fila e a fila tem que seguir o ritmo, o
primeiro a entrar é o primeiro a sair e assim por diante

// verificar se esta vazia a fila


// esvaziar fila

[Link]();
[Link]();
[Link]();
[Link]();
[Link]();
[Link]();

if ([Link]()) {
[Link]("Fila esta vazia");
} else {
[Link]("Fila: " + ninjasFila);
}

-----------------------------------------------------------------

LinkedLists x Arraylist DIFERENÇA

Qual é a diferença entre lista encadeada, linked list para um array list?
Arraylist é excelente para procurar coisas porque possui index, porem é
horrivel quando
precisa fazer um grande numero de operações Porque o algoritimo não fica
performatico

Ja o LinkedList é mais dificil para procurar, porem para inserir elementos


é extremamente simples

LINKEDLIST NA PRATICA

LinkedList<Ninja> ninjas = new LinkedList<>();

Ninja ninjaLinkedList = new Ninja(nome, idade, vila);


// addFirst adiciona em primeiro diferente do add que so adiciona
[Link](ninjaLinkedList);

// tambem tem o removeFirst que remove o primeiro

Linked list foi feito para grande volumes de dados e é a estrutura de dados
mais importante para o java

---------------------------------------------------------

HASHSET

O `HashSet` em Java é uma classe que implementa a interface `Set` e armazena


elementos de forma desordenada e sem permitir duplicatas, utilizando uma
tabela hash para seu funcionamento interno

// hashset - não possui ordenação


// ignorar itens duplicados em sua lista Set<String>
ninjasSet = new HashSet<>();
// Set<String> ninjasSet = new LinkedHashSet<>(); vai filtrar e
colocar em ordem de implementação

[Link]("Naruto");
[Link]("Naruto");
[Link]("Sasuke");
[Link]("Sakura");
[Link]("Sakura");

[Link](ninjasSet);

Você também pode gostar