La siguiente tabla muestra la diferencia entre el nivel de acceso predeterminado y protegido. Note la diferencia entre referencia y heredado.
La siguiente tabla muestra la diferencia entre el nivel de acceso predeterminado y protegido. Note la diferencia entre referencia y heredado.
vs.
En general, el punto (.) Es para el objeto en sí, la flecha (->) es para el puntero.
Un buen ejemplo que vale más que mil palabras. El siguiente ejemplo debería ser bueno.
#include <iostream> using namespace std; class Car { public: int number; void Create() { cout << "Car created, number is: " << number << "n" ; } }; int main() { Car x; // declares x to be a Car object value, // initialized using the default constructor // this very different with Java syntax Car x = new Car(); x.number = 123; x.Create(); Car *y; // declare y as a pointer which points to a Car object y = &x; // assign x's address to the pointer y (*y).Create(); // *y is object y->Create(); // same as previous line, y points to x object. It stores a reference(memory address) to x object. y->number = 456; // this is equal to (*y).number = 456; y->Create(); } |
Cuando usamos Java para escribir algo en un archivo, podemos hacerlo de las siguientes dos formas. Uno usa FileOutputStream, el otro usa FileWriter.
Usando FileOutputStream:
File fout = new File(file_location_string); FileOutputStream fos = new FileOutputStream(fout); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fos)); out.write("something"); |
Usando FileWriter:
FileWriter fstream = new FileWriter(file_location_string); BufferedWriter out = new BufferedWriter(fstream); out.write("something"); |
Ambos funcionarán, pero ¿cuál es la diferencia entre FileOutputStream y FileWriter?
Hay mucha discusión sobre cada una de esas clases, ambas son buenas implementaciones del concepto de E / S de archivos que se pueden encontrar en un sistema operativo general. Sin embargo, no nos importa cómo está diseñado, solo cómo elegir uno de ellos y por qué elegirlo de esa manera.
De la especificación de la API de Java:
FileOutputStream está diseñado para escribir flujos de bytes sin procesar, como datos de imagen. Para escribir secuencias de caracteres, considere usar FileWriter.
Si está familiarizado con los patrones de diseño, FileWriter es un uso típico del patrón Decorator en realidad. He utilizado un sencillo tutorial para demostrar el patrón Decorator, ya que es muy importante y muy útil para muchos diseños.
Una aplicación de FileOutputStream está convirtiendo un archivo en una matriz de bytes.
Mecanismo de búsqueda de texto completo
El diseño de la interfaz API de Lucene es relativamente genérico, que se parece a la estructura de la base de datos: tablas -> registro -> campo. Muchas aplicaciones, archivos y bases de datos tradicionales se pueden asignar fácilmente a la estructura de almacenamiento de Lucene / interfaz. En general, puede ver a Lucene como un sistema de base de datos que admite índices de texto completo.
Compare Lucene y la base de datos
Dado que el índice de la base de datos no está diseñado para el índice de texto completo, al usar como «% palabra clave%», el índice de la base de datos no funciona. Por lo tanto, la consulta de la base de datos con términos difusos, LIKE, puede dañar el rendimiento. Si necesita más de una palabra de coincidencia aproximada: como «% keyword1%» y como «% keyword2%» … la eficiencia también se dañará más.
Por lo tanto, para un sistema de recuperación eficiente, la clave es crear una tecnología similar como un mecanismo de indexación para indexar la fuente de datos (por ejemplo, artículos) y almacenar la tabla de palabras clave al mismo tiempo. Luego se construyen las asignaciones (artículo de palabras clave). El proceso de recuperación es solo para encontrar esas asignaciones, por lo que esto mejora en gran medida la eficiencia de la consulta de múltiples palabras clave.
La siguiente tabla compara lucene con la base de datos.
Indexación de texto Lucene | Base de datos | |
Índice | indexar la fuente de datos a través de un índice de texto completo y crear un índice inverso | Para la consulta LIKE, los datos no tienen acceso al índice tradicional, facilitado mediante el uso de coincidencias difusas al estilo GREP. |
Resultados del partido | Por el elemento de palabra (término) para que coincida, a través de la implementación de la interfaz de análisis de idioma, se pueden lograr documentos para chino y otros idiomas que no son inglés | Uso: como «% org%» también coincidirá con «organización». Varias palabras clave de concordancia aproximada: use como «% com% org%»: no puede coincidir con el orden de palabras invertido xxx.org .. xxx.com |
Pareo | Un algoritmo de coincidencia coincide (similitud) en diferente grado. | No tiene el grado de control: por ejemplo, una palabra aparece 5 veces o una vez son iguales |
La salida resultante | A través de un algoritmo especial, las mejores coincidencias se devuelven primero y se devuelve una pequeña cantidad cada vez. | Devuelve todo el conjunto de resultados que coincide, por lo que requiere mucha memoria almacenar el conjunto de resultados temporal. |
Personalización | Puede personalizar fácilmente las aplicaciones con reglas de índice (incluida la compatibilidad con el idioma chino) | Sin personalización |
Conclusión | Bueno para consultas difusas de carga alta y corpus grandes | No es eficiente, bueno para consultas no borrosas |
Innovaciones de Lucene
La mayoría de los motores de búsqueda (bases de datos) utilizan una estructura de árbol B para mantener el índice, lo que provoca muchas operaciones de E / S. Lucene se mejora agregando periódicamente estos nuevos archivos de índice pequeño en el índice grande original, por lo que no afecta la eficiencia de recuperación bajo la premisa de mejorar la eficiencia del índice.
* Mis notas de estudio para lucene, si hay algún entendimiento que no sea exactamente correcto, deje sus comentarios. Gracias.
Una vez que comprenda qué es Lucene comparándolo con la base de datos. Es fácil usar un ejemplo para comenzar.
A continuación se muestra un ejemplo simple, en el que la parte del código es bastante buena y la explicación se puede ignorar ya que no está en inglés.
Dirección: http://www.ibm.com/developerworks/cn/java/j-lo-lucene1/
Los siguientes son tres ejemplos de Java para mostrar qué son errores de sintaxis, errores semánticos y errores de tiempo de ejecución.
Error sintáctico
Si un programa contiene un error de sintaxis, no pasará la compilación.
public static int returnNull(){ System.out.println("haha"); } |
Error semántico
Si un programa contiene solo errores semánticos, significa que puede pasar la compilación, pero no hace lo que pretendía hacer. Es c
public static int calSquareArea(int sideLength){ return sideLength * 2; } |
Error de tiempo de ejecución
Los errores de tiempo de ejecución ocurren durante el tiempo de ejecución del programa.
public static void main(String[] args) { devideInt(4,0); } public static int devideInt(int a, int b){ return a/b; } |
Comparable
y Comparator
son dos interfaces proporcionadas por Java Core API. Por sus nombres, podemos decir que pueden usarse para comparar cosas de alguna manera. Pero, ¿qué son exactamente y cuál es la diferencia entre ellos? Los siguientes son dos ejemplos para responder a esta pregunta. Los ejemplos simples comparan el tamaño de dos HDTV. Cómo usar Comparable vs Comparator es obvio después de leer el código.
1. Comparable
Comparable
es implementado por una clase para poder comparar el objeto en sí mismo con algunos otros objetos. La propia clase debe implementar la interfaz para poder comparar su (s) instancia (s). El método requerido para la implementación es compareTo()
. Aquí hay un ejemplo:
class HDTV implements Comparable<HDTV> { private int size; private String brand; public HDTV(int size, String brand) { this.size = size; this.brand = brand; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } @Override public int compareTo(HDTV tv) { if (this.getSize() > tv.getSize()) return 1; else if (this.getSize() < tv.getSize()) return -1; else return 0; } } public class Main { public static void main(String[] args) { HDTV tv1 = new HDTV(55, "Samsung"); HDTV tv2 = new HDTV(60, "Sony"); if (tv1.compareTo(tv2) > 0) { System.out.println(tv1.getBrand() + " is better."); } else { System.out.println(tv2.getBrand() + " is better."); } } } |
Sony is better.
2. Comparador
En algunas situaciones, es posible que no desee cambiar una clase y hacerla comparable. En esos casos, Comparator
se puede utilizar si desea comparar objetos en función de determinados atributos / campos. Por ejemplo, se pueden comparar 2 personas en función de la «altura» o la «edad», etc. (esto no se puede hacer con el método comparable).
El método requerido para implementar es comparar(). Ahora usemos otra forma de comparar esos televisores por tamaño. Un uso común de Comparator
está ordenando. Ambas cosas Collections
y Arrays
Las clases proporcionan un método de ordenación que utiliza un Comparator
.
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; class HDTV { private int size; private String brand; public HDTV(int size, String brand) { this.size = size; this.brand = brand; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } } class SizeComparator implements Comparator<HDTV> { @Override public int compare(HDTV tv1, HDTV tv2) { int tv1Size = tv1.getSize(); int tv2Size = tv2.getSize(); if (tv1Size > tv2Size) { return 1; } else if (tv1Size < tv2Size) { return -1; } else { return 0; } } } public class Main { public static void main(String[] args) { HDTV tv1 = new HDTV(55, "Samsung"); HDTV tv2 = new HDTV(60, "Sony"); HDTV tv3 = new HDTV(42, "Panasonic"); ArrayList<HDTV> al = new ArrayList<HDTV>(); al.add(tv1); al.add(tv2); al.add(tv3); Collections.sort(al, new SizeComparator()); for (HDTV a : al) { System.out.println(a.getBrand()); } } } |
Producción:
Panasonic Samsung Sony
A menudo podemos usar Collections.reverseOrder()
método para obtener un comparador de orden descendente. Como el siguiente:
ArrayList<Integer> al = new ArrayList<Integer>(); al.add(3); al.add(1); al.add(2); System.out.println(al); Collections.sort(al); System.out.println(al); Comparator<Integer> comparator = Collections.reverseOrder(); Collections.sort(al,comparator); System.out.println(al); |
Producción:
[3,1,2] [1,2,3] [3,2,1]
3. ¿Cuándo usar cuál?
En resumen, una clase que implementa Comparable
será comparable, lo que significa que las instancias se pueden comparar entre sí.
Una clase que implementa Comparator
se utilizará principalmente en dos situaciones: 1) Se puede pasar a un método de clasificación, como Collections.sort()
o Arrays.sort()
, para permitir un control preciso sobre el orden de clasificación y 2) También se puede utilizar para controlar el orden de ciertas estructuras de datos, como conjuntos ordenados (p. ej. TreeSet
) o mapas ordenados (p. ej., TreeMap
).
Por ejemplo, para crear un TreeSet
. Podemos pasar al constructor un comparador o hacer que la clase de objeto sea comparable.
Enfoque 1 – TreeSet (comparador comparador)
class Dog { int size; Dog(int s) { size = s; } } class SizeComparator implements Comparator<Dog> { @Override public int compare(Dog d1, Dog d2) { return d1.size - d2.size; } } public class ImpComparable { public static void main(String[] args) { TreeSet<Dog> d = new TreeSet<Dog>(new SizeComparator()); // pass comparator d.add(new Dog(1)); d.add(new Dog(2)); d.add(new Dog(1)); } } |
Enfoque 2: Implemento comparable
class Dog implements Comparable<Dog>{ int size; Dog(int s) { size = s; } @Override public int compareTo(Dog o) { return o.size - this.size; } } public class ImpComparable { public static void main(String[] args) { TreeSet<Dog> d = new TreeSet<Dog>(); d.add(new Dog(1)); d.add(new Dog(2)); d.add(new Dog(1)); } } |
Referencias:
1. Comparable
2. Comparador
El siguiente es el resumen de la asignación de almacenamiento del compilador.
1. Estático vs dinámico
Estático: el compilador puede realizar el almacenamiento mirando solo el texto del programa. Una razón para la asignación estática de tantos objetos de datos como sea posible es que las direcciones de estos objetos se pueden compilar en el código de destino.
Dinámico: el almacenamiento se puede realizar observando lo que hace el programa cuando se está ejecutando.
2. Estático
A las constantes globales y otros datos generados por el compilador (por ejemplo, información para apoyar la recolección de basura) se les asigna almacenamiento estático. Las variables estáticas están vinculadas a las celdas de memoria antes de que comience la ejecución y permanecen vinculadas a la misma celda de memoria durante la ejecución. Por ejemplo, C variables estáticas.
Ventaja: eficiencia (direccionamiento directo), compatibilidad con subprogramas sensibles al historial
Desventaja: falta de flexibilidad, no hay recursividad si este es el * único * tipo de variable, como fue el caso en Fortran
3. Montón
Los datos que pueden sobrevivir a la llamada al procedimiento que los creó generalmente se asignan en un montón. Por ejemplo, nuevo para crear objetos que se pueden pasar de un procedimiento a otro.
El tamaño del montón no se puede determinar en tiempo de compilación. Se hace referencia solo a través de punteros o referencias, por ejemplo, objetos dinámicos en C ++, todos los objetos en Java
Ventaja: proporciona una gestión dinámica del almacenamiento
Desventaja: ineficiente y poco confiable
4. Apilar
A los nombres locales de un procedimiento se les asigna espacio en una pila. El tamaño de la pila no se puede determinar en tiempo de compilación.
Ventajas:
permite la recursividad
conserva el almacenamiento
Desventajas:
Gastos generales de asignación y desasignación
Los subprogramas no pueden ser sensibles al historial
Referencias ineficientes (direccionamiento indirecto)
Algunos desarrolladores han afirmado que Python es más productivo que Java. Es peligroso hacer tal afirmación, porque puede llevar varios días probarlo a fondo. Desde una vista de alto nivel, Java se escribe estáticamente, lo que significa que todos los nombres de variables deben declararse explícitamente. Por el contrario, Python se escribe dinámicamente, lo que significa que no se requiere declaración. Existe un gran debate entre la escritura dinámica y la escritura estática en los lenguajes de programación. Esta publicación no habla de eso. Sin embargo, se debe estar de acuerdo en un punto: Python es un lenguaje interpretado con una sintaxis elegante y eso lo convierte en una muy buena opción para la creación de scripts y el desarrollo rápido de aplicaciones en muchas áreas.
En esta comparación, intentaré cubrir algunos componentes básicos del lenguaje, como cadena, flujo de control, clase, herencia, E / S de archivo, etc. Todos ellos se compararán mediante el uso de ejemplos en paralelo. Espero que esto pueda proporcionar a los programadores de Java una idea general de cómo Python y Java hacen lo mismo de manera diferente. Con un vistazo al código de abajo, podemos fácilmente darnos cuenta de que el código de Python es mucho más corto, aunque algunos «shell de clase» de Java (en Java todo comienza con una definición de clase) no están en la lista. Esta podría ser una de las razones por las que Python puede ser más productivo.
También puede consultar las bibliotecas de Python y los ejemplos de código más populares.
1. Hola mundo
Comience con el programa más simple. Java necesita muchas palabras para imprimir solo una cadena. Este es el primer ejemplo que muestra que Python es más conciso.
Java | Pitón | ||
|
|
En primer lugar, hagamos lo que hagamos en Java, debemos comenzar escribiendo una clase y luego poner nuestros métodos deseados dentro. Esto a veces es muy molesto y hace perder tiempo. En Python, simplemente puede comenzar a escribir su código y luego ejecutarlo.
2. Operaciones con cadenas
|
|
Hay muchas funciones relacionadas con cadenas en Python que son tan buenas o mejores que Java, por ejemplo, lstrip (), rstrip (), etc.
3. Control de flujo
|
|
4. Clase y herencia
|
|
Cuando amplía una clase base, no hay ningún requisito, como definir un constructor explícito para el superconstructor implícito.
5. E / S de archivos
|
|
Como podemos ver, hay muchas clases que necesitamos importar para simplemente leer un archivo y, además, tenemos que manejar la excepción lanzada por algunos métodos. En Python, son dos líneas.
6. Colecciones
|
|
Estas comparaciones solo se encuentran en la superficie de Python, para la programación real, el documento de Python sigue siendo el mejor lugar para consultar.
En muchos artículos, los desarrolladores han comparado Swing con SWT con muchos detalles. Sin embargo, no existe una comparación en paralelo mediante el uso de un diagrama que pueda dar una impresión directa de en qué se diferencian. En esta publicación, compararé Swing y SWT uno al lado del otro y probaré la diferencia de esas dos bibliotecas. Como sabrá, esas dos bibliotecas tienen principalmente tres aspectos para comparar: widgets disponibles, administradores de diseño y tipos de manejo de eventos. Además de una comparación lado a lado, daré un ejemplo de código simple al final.
1. Comparación de jerarquía de clases básica.
2. Gerentes de diseño.
3. Tipos de eventos.
4. Ejemplo de código.
1. Comparación de jerarquía de clases básica.
Dado que Swing se basa en AWT y proporciona una apariencia y una sensación conectables, Swing debería tener todos los administradores de diseño de AWT. Esto puede hacer que el problema sea un poco más complicado que SWT. SWT es un sistema completo en sí mismo y no es necesario consultar otras bibliotecas. Esta puede ser otra ventaja de SWT sobre Swing.
3. Tipos de eventos.
Swing también tiene todos los eventos de AWT.
Los siguientes ejemplos de código usarán gridlayout de Swing y SWT, y agregarán un detector de acción para un botón. Puede dar una idea de cómo se usan Swing y SWT de manera diferente.
Ejemplo de código de swing:
public class TestSwing extends JFrame { public TestSwing() { JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); panel.setLayout(new GridLayout(2, 2, 50, 50)); final JLabel l1 = new JLabel("nothing"); JButton b1 = new JButton("Start"); b1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { l1.setText("Button has been clicked"); } }); panel.add(b1); panel.add(l1); panel.add(new JButton("Start")); add(panel); setTitle("Swing Example"); setSize(600, 400); setLocationRelativeTo(null); setDefaultCloseOperation(EXIT_ON_CLOSE); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { TestSwing ex = new TestSwing(); ex.setVisible(true); } }); } } |
Ejemplo de código SWT:
public class TestSWT { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 2; gridLayout.makeColumnsEqualWidth = true; shell.setLayout(gridLayout); Button b1 = new Button(shell, SWT.PUSH); b1.setText("button 1"); b1.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); final Label l2 = new Label(shell, SWT.PUSH); l2.setText("button 2"); GridData gridData = new GridData(GridData.VERTICAL_ALIGN_END); l2.setLayoutData(gridData); Button button3 = new Button(shell, SWT.PUSH); button3.setText("button 3"); button3.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent arg0) { // TODO Auto-generated method stub l2.setText("clicked"); } @Override public void widgetSelected(SelectionEvent arg0) { // TODO Auto-generated method stub l2.setText("clicked"); } }); button3.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL)); shell.pack(); shell.open(); } } |
Como Eclipse es un marco exitoso probado para el desarrollo de software extensible, SWT es una buena opción ya que son más compatibles entre sí.
Si conoce Java y desea tener una idea rápida de cómo usar Python desde el principio, el siguiente resumen puede proporcionarle una revisión rápida de los tipos de datos. También puede resultarle útil la comparación anterior de Java y Python.
Al comparar los tipos de datos entre Java y Python, puede obtener la diferencia y comenzar a usar Python rápidamente. La comparación también puede ayudar a los desarrolladores a comprender los conceptos comunes compartidos por diferentes lenguajes de programación.
Aparentemente, Java tiene más tipos / estructuras de datos que Python, por lo que enumeraré el concepto más similar de Java para los tipos de datos de Python correspondientes.
1. Cuerdas
Java | Pitón | ||
|
|
En Python, la cadena puede residir en un par de comillas simples y en un par de comillas dobles. Admite la multiplicación: «x» * 3 es «xxx».
2. Números
Java | Pitón | ||
|
|
En Java, cuando escribe algo como 1.01, se interpreta como un doble.
Double es un punto flotante IEEE 754 de precisión de 64 bits, mientras que float es un punto flotante IEEE 754 de precisión de 32 bits.
Como un flotante es menos preciso que un doble, la conversión no se puede realizar implícitamente.
3. Nulo
Java | Pitón | ||
|
|
4. Listas
Java | Pitón | ||
|
|
5. Tuplas
Java | Pitón | |
No hay tuplas en Java. |
|
En Python, las tuplas son similares con las listas, y la diferencia entre ellas es que la tupla es inmutable. Eso significa que los métodos que cambian el valor de las listas no se pueden usar en tuplas.
Para asignar una tupla de un solo elemento, tiene que ser: aTuple = (5,). Si se quita la coma, será incorrecto.
6. Conjuntos
Java | Pitón | ||
|
|
7. Diccionarios
Los diccionarios en Python son como los mapas en Java.
Java | Pitón | ||
|
|
Más sobre las colecciones de Java: