Заголовок Content-Encoding
является заголовком ответа, который предоставляет сервер.
Обычно клиент предоставляет заголовок Accept-Encoding
, чтобы указать, какую кодировку контента вы хотите запросить.
Например: Accept-Encoding: gzip, deflate
См. MDN на Сжатие с помощью gzip
Однако этот конкретный заголовок помечен как запрещенный заголовок , что означает это не может быть установлено программно Javascript, который выполняется в браузере (однако все еще работает в Node).
Большинство браузеров автоматически добавляют заголовок Accept-Encoding
, содержащий все кодировки контента, которые он поддерживает.
Полагаю, очевидные варианты:
o Переключиться на временную структуру данных (компоновщик) для обновления. Это вполне нормально. StringBuilder
для манипуляции String
. Как ваш пример.
Person p3 =
Builder.update(p)
.withAddress(
Builder.update(p.address())
.withCity("Berlin")
.build()
)
.build();
o Всегда используйте постоянные структуры. Несмотря на то, что копирование выглядит много, на самом деле вы должны делиться почти всеми состояниями, так что это далеко не так плохо, как кажется.
final Person p3 = p
.withAddress(
p.address().withCity("Berlin")
);
o Разобрать структуру данных на множество переменных и рекомбинировать с одним огромным и запутанным конструктором.
final Person p3 = Person.of(
p.name(),
Address.of(
p.house(), p.street(), "Berlin", p.country()
),
p.x(),
p.y(),
p.z()
);
o Использовать интерфейсы обратного вызова для предоставления новых данных. Еще более шаблонный.
final Person p3 = Person.of(new PersonInfo(
public String name () { return p.name(); )
public Address address() { return Address.of(new AddressInfo() {
private final Address a = p.address();
public String house () { return a.house() ; }
public String street () { return a.street() ; }
public String city () { return "Berlin" ; }
public String country() { return a.country(); }
})),
public Xxx x() { return p.x(); }
public Yyy y() { return p.y(); }
public Zzz z() { return p.z(); }
});
o Используйте мерзкие хаки, чтобы сделать поля временно доступными для кода.
final Person p3 = new PersonExploder(p) {{
a = new AddressExploder(a) {{
city = "Berlin";
}}.get();
}}.get();
(Как ни странно, я только что написал Крис Окасаки, «Чисто функциональные структуры данных»).
Очень трудно, если не невозможно, сделать вещи неизменными, если они не предназначены.
Если Вы можете создавать с нуля:
Взгляните на Функциональную Java . В настоящее время предоставляются постоянные структуры данных:
Ряд примеров использования предоставляется с двоичным распределением.
Следуйте очень простой процедуре с динамическим прокси:
class ImmutableBuilder {
static <T> T of(Immutable immutable) {
Class<?> targetClass = immutable.getTargetClass();
return (T) Proxy.newProxyInstance(targetClass.getClassLoader(),
new Class<?>[]{targetClass},
immutable);
}
public static <T> T of(Class<T> aClass) {
return of(new Immutable(aClass, new HashMap<String, Object>()));
}
}
class Immutable implements InvocationHandler {
private final Class<?> targetClass;
private final Map<String, Object> fields;
public Immutable(Class<?> aTargetClass, Map<String, Object> immutableFields) {
targetClass = aTargetClass;
fields = immutableFields;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("toString")) {
// XXX: toString() result can be cached
return fields.toString();
}
if (method.getName().equals("hashCode")) {
// XXX: hashCode() result can be cached
return fields.hashCode();
}
// XXX: naming policy here
String fieldName = method.getName();
if (method.getReturnType().equals(targetClass)) {
Map<String, Object> newFields = new HashMap<String, Object>(fields);
newFields.put(fieldName, args[0]);
return ImmutableBuilder.of(new Immutable(targetClass, newFields));
} else {
return fields.get(fieldName);
}
}
public Class<?> getTargetClass() {
return targetClass;
}
}
использование:
interface Person {
String name();
Person name(String name);
int age();
Person age(int age);
}
public class Main {
public static void main(String[] args) {
Person mark = ImmutableBuilder.of(Person.class).name("mark").age(32);
Person john = mark.name("john").age(24);
System.out.println(mark);
System.out.println(john);
}
}
направления роста:
надеюсь, что это поможет:)
Хотите неизменности:
В обоих случаях есть более простые способы достижения желаемого результата.
Остановить внешний код от изменения данных легко с помощью интерфейсов:
public interface Person {
String getName();
Address getAddress();
}
public interface PersonImplementor extends Person {
void setName(String name);
void setAddress(Address address);
}
public interface Address {
String getCity();
}
public interface AddressImplementor {
void setCity(String city);
}
Затем, чтобы остановить изменение значения, как только набор также " просто »с помощью java.util.concurrent.atomic.AtomicReference (хотя может потребоваться изменить режим гибернации или какой-либо другой уровень персистентности):
class PersonImpl implements PersonImplementor {
private AtomicReference<String> name;
private AtomicReference<Address> address;
public void setName(String name) {
if ( !this.name.compareAndSet(name, name)
&& !this.name.compareAndSet(null, name)) {
throw new IllegalStateException("name already set to "+this.name.get()+" cannot set to "+name);
}
}
// .. similar code follows....
}
Но зачем вам нужно нечто большее, чем просто интерфейсы для выполнения задачи?
Строители сделают ваш код слишком многословным, чтобы его можно было использовать. На практике почти все неизменяемые структуры данных, которые я видел, передаются в состоянии через конструктор. Во что бы то ни стало, вот хорошая серия публикаций, описывающих неизменяемые структуры данных в C # (которые должны легко конвертироваться в Java):
C # и Java чрезвычайно многословны, поэтому код в этих статьях довольно страшный. Я рекомендую изучить OCaml, F # или Scala и ознакомиться с неизменяемостью этих языков. Освоив эту технику, вы сможете гораздо проще применять тот же стиль кодирования к Java.
Я реализовал несколько постоянных структур данных на Java. Весь открытый исходный код (GPL) в коде Google для всех, кому интересно:
http://code.google.com/p/mikeralib/source/browse/#svn/trunk/Mikera/src/mikera/persistent
Основные из них: