Что “статично”?

Работа с: $string = 'one,two,one,five,seven,bag,tea';

Если вы генерируете строку в любой точке «сценария вверх», то вы должны удалять дубликаты по мере их появления.

Допустим, вы используете конкатенацию для генерации вашей строки, например:

$string='';
foreach($data as $value){
    $string.=(strlen($string)?',':'').some_func($value);
}

... тогда вам нужно извлечь уникальные значения из $string на основе разделителя (запятая), а затем повторно взорваться с разделителем.


Я предлагаю вам разработать более прямой метод и запретить дубликаты внутри начального цикла foreach, например:

foreach($data as $value){
    $return_value=some_func($value);  // cache the returned value so you don't call the function twice
    $array[$return_value]=$return_value;  // store the return value in a temporary array using the function's return value as both the key and value in the array.
}
$string=implode(',',$array);  // clean: no duplicates, no trailing commas

Это работает, потому что никогда не допускается существование дублирующих значений. Все последующие вхождения будут использоваться для перезаписи предыдущего вхождения. Этот бесполезный фильтр работает, потому что массивы могут не иметь двух одинаковых ключей в одном массиве (уровне).

В качестве альтернативы, вы можете избежать «перезаписи» данных массива в цикле, вызвав if(!isset($array[$return_value])){$array[$return_value]=$return_value;}, но различие означает вызов функции isset() на каждой итерации. Преимущество использования этих ассоциативных назначений клавиш состоит в том, что процесс избегает использования in_array(), который медленнее, чем isset().

Все это говорит о том, что если вы извлекаете столбец данных из двумерного массива, например:

$string='';
foreach($data as $value){
    $string.=(strlen($string)?',':'').$value['word'];
}

Тогда вы можете использовать магию array_column() без цикла , как это :

echo implode(',',array_column($str,'word','word'));

И, наконец, для тех, кто интересуется микрооптимизацией, отмечу, что один вызов array_unique() на самом деле медленнее, чем несколько двухфункциональных методов. Подробнее читайте здесь .

Суть в том, что есть много способов выполнить эту задачу. explode->unique->implode может быть наиболее кратким методом в некоторых случаях, если вы не генерируете строку с разделителями, но вряд ли это будет самый прямой или самый быстрый метод. Выберите для себя, что лучше для вашей задачи.

10
задан RBerteig 27 May 2009 в 01:40
поделиться

6 ответов

Концепция static имеет отношение к тому, является ли что-то частью класса или объекта (экземпляра).

В случае main , который объявлен как static , он говорит, что метод main является методом класса - методом, который является частью класса, а не частью объекта. Это означает, что другой класс может вызвать метод класса другого класса, ссылаясь на ClassName.method . Например, вызов метода выполнения MyClass будет выполняться следующим образом:

MyClass.main(new String[]{"parameter1", "parameter2"});

С другой стороны, метод или поле без модификатора static означает, что он является частью объекта (или также называемый «экземпляром»), а не частью класса. На него ссылаются по имени конкретного объекта, которому принадлежит метод или поле, а не по имени класса:

MyClass c1 = new MyClass();
c1.getInfo()     // "getInfo" is an instance method of the object "c1"

Поскольку каждый экземпляр может иметь разные значения, значения метода или поля с одинаковым именем в разных объекты не обязательно должны быть одинаковыми:

MyClass c1 = getAnotherInstance();
MyClass c2 = getAnotherInstance();

c1.value     // The field "value" for "c1" contains 10.
c2.value     // The field "value" for "c2" contains 12.
             // Because "c1" and "c2" are different instances, and 
             // "value" is an instance field, they can contain different
             // values.

Объединение двух концепций переменных экземпляра и класса. Допустим, мы объявляем новый класс, который содержит переменные и методы как экземпляра, так и класса:

class AnotherClass {
    private int instanceVariable;
    private static int classVariable = 42;

    public int getInstanceVariable() {
        return instanceVariable;
    }

    public static int getClassVariable() {
        return classVariable;
    }

    public AnotherClass(int i) {
        instanceVariable = i;
    }
}

Вышеупомянутый класс имеет переменную экземпляра instanceVariable и переменную класса classVariable , которая объявлена ​​с модификатор static . Точно так же существует метод экземпляра и класса для получения значений.

Конструктор экземпляра принимает значение, которое нужно присвоить переменной экземпляра в качестве аргумента. Переменная класса инициализируется как 42 и никогда не менялась.

Давайте фактически воспользуемся указанным выше классом и посмотрим, что произойдет:

AnotherClass ac1 = new AnotherClass(10);

ac1.getInstanceVariable();             // Returns "10"
AnotherClass.getClassVariable();       // Returns "42"

Обратите внимание на разные способы вызова методов класса и экземпляра. То, как они ссылаются на класс по имени AnotherClass или экземпляр по имени ac1 . Давайте пойдем дальше и посмотрим на различия в поведении методов:

AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);

ac1.getInstanceVariable();             // Returns "10"
AnotherClass.getClassVariable();       // Returns "42"
ac2.getInstanceVariable();             // Returns "20"
AnotherClass.getClassVariable();       // Returns "42"

Как можно видеть, переменная экземпляра - это переменная, которая хранится в объекте (или «экземпляре»), поэтому уникальна для этого конкретного экземпляра, который в этом примере является объекты, указанные в ac1 и ac2 .

Переменная класса, с другой стороны, уникальна только для всего этого класса. Чтобы еще лучше понять эту точку зрения, давайте добавим новый метод в AnotherClass :

public int getClassVariableFromInstance() {
    return classVariable;
}

Затем, выполните следующее:

AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);

ac1.getInstanceVariable();             // Returns "10"
ac1.getClassVariableFromInstance();    // Returns "42"
ac2.getInstanceVariable();             // Returns "20"
ac2.getClassVariableFromInstance();    // Returns "42"

Хотя getClassVariableFromInstance является методом экземпляра, что можно увидеть, если вызвать его, обратившись к экземплярам ac1 и ac2 , они оба вернуть то же значение, 42 . Это связано с тем, что в обоих методах экземпляра они ссылаются на метод класса classVariable , который уникален для класса, а не для экземпляра - существует только одна копия classVariable для class AnotherClass .

Я надеюсь, что кое-что проясняет, для чего используется модификатор static .

В Руководстве по Java от Sun есть раздел под названием Понимание членов экземпляра и класса , которое также относится к двум типам переменных и методов.

AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);

ac1.getInstanceVariable();             // Returns "10"
ac1.getClassVariableFromInstance();    // Returns "42"
ac2.getInstanceVariable();             // Returns "20"
ac2.getClassVariableFromInstance();    // Returns "42"

Хотя getClassVariableFromInstance является методом экземпляра, что можно увидеть, вызвав его, обратившись к экземплярам ac1 и ac2 , они оба возвращают одно и то же значение. , 42 . Это связано с тем, что в обоих методах экземпляра они ссылаются на метод класса classVariable , который уникален для класса, а не для экземпляра - существует только одна копия classVariable для class AnotherClass .

Я надеюсь, что кое-что проясняет, для чего используется модификатор static .

В Руководстве по Java от Sun есть раздел под названием Понимание членов экземпляра и класса , которое также относится к двум типам переменных и методов.

AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);

ac1.getInstanceVariable();             // Returns "10"
ac1.getClassVariableFromInstance();    // Returns "42"
ac2.getInstanceVariable();             // Returns "20"
ac2.getClassVariableFromInstance();    // Returns "42"

Хотя getClassVariableFromInstance является методом экземпляра, что можно увидеть, вызвав его, обратившись к экземплярам ac1 и ac2 , они оба возвращают одно и то же значение. , 42 . Это связано с тем, что в обоих методах экземпляра они ссылаются на метод класса classVariable , который уникален для класса, а не для экземпляра - существует только одна копия classVariable для class AnotherClass .

Я надеюсь, что кое-что проясняет, для чего используется модификатор static .

В Руководстве по Java от Sun есть раздел под названием Понимание членов экземпляра и класса , которое также относится к двум типам переменных и методов.

как можно увидеть при вызове с помощью ссылки на экземпляры ac1 и ac2 , они оба возвращают одно и то же значение, 42 . Это связано с тем, что в обоих методах экземпляра они ссылаются на метод класса classVariable , который уникален для класса, а не для экземпляра - существует только одна копия classVariable для class AnotherClass .

Я надеюсь, что кое-что проясняет, для чего используется модификатор static .

В Руководстве по Java от Sun есть раздел под названием Понимание членов экземпляра и класса , которое также относится к двум типам переменных и методов.

как можно увидеть при вызове с помощью ссылки на экземпляры ac1 и ac2 , они оба возвращают одно и то же значение, 42 . Это связано с тем, что в обоих методах экземпляра они ссылаются на метод класса classVariable , который уникален для класса, а не для экземпляра - существует только одна копия classVariable для class AnotherClass .

Я надеюсь, что кое-что проясняет, для чего используется модификатор static .

В Руководстве по Java от Sun есть раздел под названием Понимание членов экземпляра и класса , которое также относится к двум типам переменных и методов.

23
ответ дан 3 December 2019 в 14:00
поделиться

См. Красивое описание в Википедии

Например, обратите внимание, как в классе Math вы можете говорить такие вещи, как

Math.Abs(x);

, не говоря

Math m = new Math();

Это статические методы, поскольку вам не нужен экземпляр. Методы экземпляра - это те методы, которые требуют наличия экземпляра класса.

Employee e = new Employee();
e.Terminate();
11
ответ дан 3 December 2019 в 14:00
поделиться

Статический метод - это метод, который применяется к классу в целом, а не к какому-либо конкретному члену. .goExtinct () будет методом всей популяции уток, а не какой-то конкретной утки. main является общедоступным и статическим, потому что он всегда должен быть доступен и не является частью какого-либо конкретного класса.

2
ответ дан 3 December 2019 в 14:00
поделиться

Обычно у вас должен быть объект, экземпляр класса, чтобы вызывать для него методы, как минимум по двум причинам:

  1. Это зависит от объекта, который реализует класс вызываемый метод. Например, если у вас есть экземпляр подкласса, вместо этого будет вызываться метод подкласса, даже если код, вызывающий метод, тот же.
  2. Объекты обычно имеют внутреннее состояние (поля), эти методы могут ссылаться на . Это не работает, если нет экземпляра объекта.

Вы создаете экземпляры объекта, вызывая конструктор класса:

MyObject a = new MyObject();

Статические методы - это методы, которые не прикреплены к экземплярам объектов. Их можно вызвать, просто назвав класс.

1
ответ дан 3 December 2019 в 14:00
поделиться

В любом объектно-ориентированном языке программирования, таком как Java или C ++, вы создаете классы, которые на самом базовом уровне похожи на BluePrints здания. Вы можете посмотреть на план и определить, как связаны различные компоненты, но вы не можете жить в нем. То же самое с классами и объектами. Классы - это план, и вы создаете экземпляр класса, который называется объектом. Для одного и того же чертежа у вас может быть несколько зданий, так же как для одного класса у вас может быть несколько объектов. Объект - это экземпляр класса. Каждый метод в классе может быть вызван для объекта или экземпляра класса, тогда как для вызова статических методов вам фактически не нужен экземпляр, вы можете напрямую вызвать ClassName.method () без фактического создания экземпляра класса.

0
ответ дан 3 December 2019 в 14:00
поделиться

В этом конкретном случае основной метод должен быть статическим, поскольку JVM начинает загружать классы и создавать объекты. Когда вы запускаете программу Java, JVM будет искать определение класса, который был ей передан, и загружать его. Таким образом, java MyClass приведет к загрузке определения класса MyClass.

По определению, программа на Java начнет выполняться в методе main () класса, который был передан JVM в качестве класса для первоначальной загрузки. В этот момент времени не было создано ни одного экземпляра (объекта) типа MyClass, поэтому основной метод должен быть статическим, чтобы разрешить начало выполнения вашей программы.

Если вы хотите увидеть, какие классы загружаются во время для выполнения программы Java можно использовать параметр командной строки -verbose: class.

1
ответ дан 3 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: